现在的位置: 首页 > 综合 > 正文

2012杭州现场赛

2013年07月16日 ⁄ 综合 ⁄ 共 4246字 ⁄ 字号 评论关闭

Outlets

看一眼就应该知道是要求MST。

#include <stdio.h>
#include <string.h>
#include <math.h>
#include <algorithm>
using namespace std;
const int N=10000;
struct DST
{
    int father[N];
    void init()
    {
        for (int i=0; i<N; i++) father[i]=i;
    }
    int root(int k)
    {
        if (father[k]==k) return k;
        father[k]=root(father[k]);
        return father[k];
    }
    void merge(int x, int y)
    {
        x=root(x),y=root(y);
        father[x]=father[y];
    }
}s;
struct _point
{
    int x,y;
    double d;
}site[60],edge[N];
inline bool cmp(const _point &a, const _point &b)
{
    return (a.d<b.d);
}
int main()
{
    int i,j,k,n,p,q,x,y,K;
    double tot;
    while (scanf("%d",&n),n)
    {
        s.init();
        scanf("%d %d",&p, &q);
        for (i=1; i<=n; i++)
        {
            scanf("%d %d",&site[i].x,&site[i].y);
        }
        for (i=1,k=0; i<=n; i++)
          for (j=1; j<=n; j++)
          if (i!=j)
          {
            edge[k].d=sqrt(
                (site[i].x-site[j].x)*(site[i].x-site[j].x)
                +(site[i].y-site[j].y)*(site[i].y-site[j].y)+0.0);
            edge[k].x=i, edge[k].y=j;
            k++;
          }
        K=k;
        sort(edge,edge+K,cmp);
        tot=sqrt(
                (site[p].x-site[q].x)*(site[p].x-site[q].x)
                +(site[p].y-site[q].y)*(site[p].y-site[q].y)+0.0);
        s.merge(p,q);
        for (i=1,k=2; k<n; i++)
        {
            x=edge[i].x, y=edge[i].y;
            x=s.root(x), y=s.root(y);
            if (x==y) continue;
            s.merge(x,y);
            tot+=edge[i].d;
            k++;
        }
        printf("%.2f\n",tot);

    }
    return 0;
}

 

Friend Chains

点V=1000,边E=10000,floyd不靠谱,单点最短路径bfs的复杂度是O(V+E),跑V次O(V^2+VE),可以接受,水过。

那个名字用map来hash就好了

#include <stdio.h>
#include <string.h>
#include <string>
#include <map>
using namespace std;
const int V = 1010;
const int E = 25010;
int n;
int g[V][V],cnt;
struct node{
    int x,y,w;
    node *next;
}edge[E],*head[V];
inline void addedge(int x, int y, int w){
    edge[cnt].x=x, edge[cnt].y=y, edge[cnt].w=w;
    edge[cnt].next=head[x]; head[x]=edge+cnt++;
}
void init(){
    cnt=0;
    memset(head,0,sizeof(head));
    memset(g,0,sizeof(g));
}
int q[V],vis[V],dis[V];
int bfs(int st){
    int he,ta,now;//head tail
    he=1,ta=0;
    memset(vis,0,sizeof(vis));
    memset(dis,7,sizeof(dis));
    q[0]=st;
    vis[st]=true;
    dis[st]=0;
    while (ta<he){
        now=q[ta++];
        //vis[now]=true;//useless
        for (node* p=head[now]; p; p=p->next){
            if (!vis[p->y] && dis[p->y]>dis[now]+p->w)
            {
                q[he++]=p->y;
                vis[p->y]=true;
                dis[p->y]=dis[now]+p->w;
            }
        }
    }
    int i,max=0;
    for (i=0; i<n; i++)
      if (dis[i]>max) max=dis[i];
    return max;
}
int main()
{
    map<string,int> name;
    char str[11],s1[11],s2[11];
    int m,i,j,k,x,y;
    while ( scanf("%d",&n),n){
        init();
        name.clear();
        k=0;
        for (i=0; i<n; i++)
        {
            scanf("%s",str);
            name[str]=i;
        }
        scanf("%d",&m);
        for (i=0; i<m; i++)
        {
            scanf("%s %s",s1,s2);
            x=name[s1], y=name[s2];
            g[x][y]=g[y][x]=1;
        }
        for (i=0; i<n; i++)
         for (j=0; j<n; j++)
          if (g[i][j]) addedge(i,j,1);
        int tmp;
        for (i=0,k=0; i<n; i++)
        {
            tmp=bfs(i);
            if (tmp>k) k=tmp;
            if (k>=n) break;
        }
        if (k>=n) k=-1;
        printf("%d\n",k);
    }
    return 0;
}

Scaring the Birds

这题二分稻草人的数量,dfs枚举稻草人的组合,然后验证即可。

n似乎不大,直接用循环赋值应该就能A,用线段树求覆盖长度是在干嘛。。。
 

#include <cstdio>
#include<cstring>
using namespace std;
#define L(u) ( u << 1 )
#define R(u) ( u << 1 | 1 )
#define N 55
struct item{ int l, r; int v, add;};
struct tree{
    item node[N*3];
    int num[N];
    int n, q;
    void init ( int u, int l, int r )
    {
        node[u].l = l;
        node[u].r = r;
        node[u].v = 0;
        node[u].add = 0;
        if ( l == r ) return;
        int mid = ( l + r ) >> 1;
        init ( L(u), l, mid );
        init ( R(u), mid+1, r );
    }
    int set ( int u, int l, int r)
    {
        int ret = 0;
        if ( node[u].v ==  node[u].r-node[u].l+1 ) return 0;
        if ( l == node[u].l && node[u].r == r ) {
            ret = r-l+1-node[u].v;
            node[u].v = r-l+1;
            return ret;
        }
        int mid = ( node[u].l + node[u].r ) >> 1;
        if ( r <= mid )
            ret = set ( L(u), l, r );
        else if ( l > mid )
            ret = set ( R(u), l, r );
        else {
            ret = set ( L(u), l, mid );
            ret+= set ( R(u), mid+1, r );
        }
        node[u].v += ret;
        return ret;
    }
    int sum ( int u, int l, int r )
    {
        if ( node[u].v ==  node[u].r-node[u].l+1 ) return r-l+1;
        if ( l == node[u].l && node[u].r == r ) {
            return node[u].v;
        }
        int mid = ( node[u].l + node[u].r ) >> 1;
        if ( r <= mid )
            return sum ( L(u), l, r );
        else if ( l > mid )
            return sum ( R(u), l, r );
        else
            return (sum ( L(u), l, mid ) + sum ( R(u), mid+1, r ));
    }
}s[N];
struct Vac{
    int x,y,r,vis;
}V[N];
bool check(int n, int k, int mid){
    int i,j,l,r,p;
    for (i=1; i<=n; i++) s[i].init(1,1,n);
    for (i=0; i<k; i++){
      s[ V[i].y ].set(1, V[i].x, V[i].x);
      if (V[i].vis) {
        for (j=0; j<=V[i].r; j++){
            l=V[i].x-(V[i].r-j), r=V[i].x+V[i].r-j;
            if (l<=0) l=1;
            if (r>=n) r=n;
            p=V[i].y-j;
            if (p>=1) s[p].set(1,l,r);
            p=V[i].y+j;
            if (p<=n) s[p].set(1,l,r);
        }
      }
    }
    for (i=1, j=0; i<=n; i++) j+=s[i].sum(1,1,n);
    if (j==n*n) return true; else return false;
}
bool dfs(int n,int k, int d, int mid, int p){
    if (d==mid){
        return check(n,k,mid);
    }
    bool tmp;
    for (int i=p; i<k; i++){
        if (V[i].vis==0){
            V[i].vis=1;
            tmp=dfs(n,k,d+1,mid,i+1);
            V[i].vis=0;
            if (tmp) return true;
        }
    }
    return false;
}
int solve(int n, int k){
    int l,r,mid;
    l=0, r=k+1;
    while (l<r){
        mid=(l+r)>>1;
        if ( dfs(n,k,0,mid,0) ) r=mid; else l=mid+1;
    }
    if (l==k+1) return -1; else return l;
}
int main(){
    int i,k,n;
    while ( scanf("%d",&n), n ){
        scanf("%d",&k);
        for (i=0; i<k; i++) scanf("%d %d",&V[i].x,&V[i].y);
        for (i=0; i<k; i++) scanf("%d",&V[i].r);
        printf("%d\n",solve(n,k));
    }
    return 0;
}

 

 

 

 

 

 

 

 

 

【上篇】
【下篇】

抱歉!评论已关闭.