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
  • 相关阅读:
    js 将内容复制到剪切板上
    javascript刷新父页面的各种方法汇总
    jQuery 使得文本框获得焦点
    layui switch 开关监听 弹出确定状态转换
    layui 图片上传+表单提交+ Spring MVC
    python爬虫实例--网易云音乐排行榜爬虫
    Python爬虫html解析工具beautifulSoup在pycharm中安装及失败的解决办法
    python爬虫实例--博客园首页Java目录博文爬虫
    让js中的函数只有一次有效调用的三种常用方法
    spring项目获取ServletContext
  • 原文地址:https://www.cnblogs.com/yours1103/p/3577505.html
Copyright © 2011-2022 走看看