zoukankan      html  css  js  c++  java
  • zoj 3761

    很简单但很虐心的一道题;

    我感觉自己的算法没错,但是老是过不了;= =

    但是还是把代码贴出来;

    我的方法,用并查集的方式做一课树,然后对树进行遍历;

    有多少棵树就有多少个点剩余;

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #define inf 1000000000
    #define maxn 2009
    using namespace std;
    
    struct node
    {
        int x;
        int y;
        int p;
        int sum;
        int son[5];
        bool operator <(const node &t)const
        {
            if(x==t.x)
                return y<t.y;
            else return x<t.x;
        }
    } no[maxn];
    
    int f[maxn];
    int find(int x)
    {
        return f[x]==x?x:f[x]=find(f[x]);
    }
    
    int dis(int a,int b)
    {
        return(abs(no[a].x-no[b].x)+abs(no[a].y-no[b].y));
    }
    
    bool check(int a,int b)
    {
        bool flag=1;
       if(no[a].x!=no[b].x&&no[a].y!=no[b].y)
            flag=0;
        if(find(b)==a)flag=0;
        if(no[b].sum>=4)flag=0;
        return flag;
    }
    
    void dfs(int root)
    {
        for(int i=0;i<no[root].sum;i++)
            dfs(no[root].son[i]);
        if(no[root].p!=-1)
        {
           if(no[root].x==no[no[root].p].x)
            {
               if(no[root].y<no[no[root].p].y)
                {
                   printf("(%d, %d) UP
    ",no[root].x,no[root].y);
                }
                else printf("(%d, %d) DOWN
    ",no[root].x,no[root].y);
            }
            else if(no[root].y==no[no[root].p].y)
            {
               if(no[root].x<no[no[root].p].x)
                   printf("(%d, %d) RIGHT
    ",no[root].x,no[root].y);
                else printf("(%d, %d) LEFT
    ",no[root].x,no[root].y);
            }
        }
    }
    
    int main()
    {
        int n;
        int tar,d;
        while(scanf("%d",&n)!=EOF)
        {
            for(int i=0; i<n; i++)
            {
               scanf("%d%d",&no[i].x,&no[i].y);
                no[i].p=-1;
                f[i]=i;
                no[i].sum=0;
            }
            for(int i=0; i<n; i++)
            {
                d=inf;
                tar=-1;
                for(int j=0; j<n;j++)
                {
                   if(i==j) continue;
                   if(dis(i,j)<d&&check(i,j))
                   {
                       d=dis(i,j);
                       tar=j;
                   }
                }
               if(tar==-1){no[i].p=-1;continue;}
                no[i].p=tar;
                f[i]=tar;
                no[tar].son[no[tar].sum++]=i;
            }
            int ans=0;
            for(int i=0; i<n; i++)
               if(no[i].p==-1)
                   ans++;
            printf("%d
    ",ans);
            for(int i=0; i<n; i++)
            {
                if(no[i].p==-1)
                   dfs(i);
            }
        }
        return 0;
    }
    /*
    18
    1 1
    2 1
    2 2
    4 2
    5 2
    6 2
    2 3
    3 3
    4 3
    5 3
    7 3
    5 4
    8 4
    1 5
    2 5
    3 5
    4 5
    5 5
    */
    View Code

    感谢文蔚大叔给我出了一组数据,让我意识到自己的算法的缺陷;

    我先前的做法是构造一棵树,但是发现用贪心的方法建树的时候可能会把本来的一棵树变成两棵树,这样的话就错了;

    所以我后来改成一个图,然后再图中dfs,这样的话就没错了;

    #include<cstdio>
    #include<cstring>
    #define maxn 2009
    #include<algorithm>
    #define inf 1e9
    using namespace std;
    char s[4][10]={"LEFT","DOWN","RIGHT","UP"};
    struct node
    {
        int x,y;
        int son[4];
        int d[4];
    } no[maxn];
    bool vis[maxn];
    int f[maxn];
    
    int check(int a,int b)
    {
        return (abs(no[a].x-no[b].x)+abs(no[a].y-no[b].y));
    }
    
    int find(int x)
    {
        return f[x]==x?x:f[x]=find(f[x]);
    }
    
    void un(int x,int y)
    {
        int a=find(x);
        int b=find(y);
        if(a!=b)
            f[a]=b;
        return;
    }
    
    void dfs(int x,int f)
    {
        vis[x]=1;
        for(int i=0;i<4;i++)
        {
            int v=no[x].son[i];
            if(v!=-1&&!vis[v])
            {
                dfs(v,x);
            }
        }
        if(f!=-1)
        {
            for(int i=0;i<4;i++)
            {
                if(no[f].son[i]==x)
                {
                    printf("(%d, %d) %s
    ",no[x].x,no[x].y,s[i]);
                }
            }
        }
    }
    
    int main()
    {
        int n;
        while(scanf("%d",&n)!=EOF)
        {
            for(int i=0; i<n; i++)
            {
                scanf("%d%d",&no[i].x,&no[i].y);
                for(int j=0; j<4; j++)
                {
                    no[i].son[j]=-1;
                    no[i].d[j]=inf;
                    f[i]=i;
                }
            }
            for(int i=0; i<n; i++)
            {
                for(int j=0; j<n; j++)
                {
                    if(i==j)continue;
                    if(no[i].x==no[j].x)
                    {
                        un(i,j);
                        if(no[j].y<no[i].y)
                        {
                            if(check(i,j)<no[i].d[3])
                            {
                                no[i].son[3]=j;
                                no[i].d[3]=check(i,j);
                            }
                        }
                        else
                        {
                            if(check(i,j)<no[i].d[1])
                            {
                                no[i].son[1]=j;
                                no[i].d[1]=check(i,j);
                            }
                        }
                    }
                    else if(no[i].y==no[j].y)
                    {
                        un(i,j);
                        if(no[j].x<no[i].x)
                        {
                            if(check(i,j)<no[i].d[2])
                            {
                                no[i].son[2]=j;
                                no[i].d[2]=check(i,j);
                            }
                        }
                        else
                        {
                            if(check(i,j)<no[i].d[0])
                            {
                                no[i].son[0]=j;
                                no[i].d[0]=check(i,j);
                            }
                        }
                    }
                }
            }
            int ans=0;
            for(int i=0;i<n;i++)
            {
                if(f[i]==i)
                    ans++;
            }
            printf("%d
    ",ans);
            memset(vis,0,sizeof vis);
            for(int i=0;i<n;i++)
            {
                dfs(i,-1);
            }
        }
        return 0;
    }
    View Code
  • 相关阅读:
    kafka学习
    centos/Fedora/RHEL 安全设置
    cordon、drain、delete node区别
    HARBOR 仓库 API功能接口
    gcr 镜像无法下载问题
    linux系统 重启盘符错乱问题
    Kafka史上最详细原理总结
    redis 部署
    mongodb4.0 安装
    gitstats 统计gitlab仓库中的代码
  • 原文地址:https://www.cnblogs.com/yours1103/p/3577505.html
Copyright © 2011-2022 走看看