zoukankan      html  css  js  c++  java
  • hdu 4946 Area of Mushroom (凸包,去重点,水平排序,留共线点)

    题意:

      在二维平面上,给定n个人

      每个人的坐标和移动速度v

      若对于某个点,只有 x 能最先到达(即没有人能比x先到这个点或者同时到这个点)

      则这个点称作被x占有,若有人能占有无穷大的面积 则输出1 ,否则输出0

    思路:

      1、把所有点按速度排个序,然后把不是最大速度的点去掉

      剩下的点才有可能是占有无穷大的面积

      2、给速度最大的点做个凸包,则只有在凸包上的点才有可能占有无穷大

      若一个位置有多个人,则这几个人都是不能占有无穷大的。

      凸包上边里共线的点是要保留的。

    #易错点:

         1.凸包边上要保留共线的点,最好采用水平排序(构造凸包前)

      2.对于去重点,必须在构造完凸包之后。

    WA:构造凸包之前去重点(构造凸包的点不包括有重复的点)

    #include<stdio.h>
    #include<algorithm>
    #include<fstream>
    #include<string.h>
    #include<iostream>
    using namespace std;
    const int MAX=550;
    struct point
    {
        int x;
        int y;
        int v;
        int i;
    }p[MAX],Ini[MAX],res[MAX];
    int ans[MAX];
    bool cmp(point A,point B)
    {
        if(A.y==B.y)return A.x<B.x;
        return A.y<B.y;
    }
    bool cmp1(point A,point B)
    {
        if(A.v>B.v)return true;
        if(A.v==B.v)
        {
            if(A.x<B.x)return true;
            if(A.x==B.x&&A.y<B.y)return true;
        }
        return false;
    }
    int cross(point A,point B,point C)
    {
        return (B.x-A.x)*(C.y-A.y)-(C.x-A.x)*(B.y-A.y);
    }
    int Graham(point *p,int n)
    {
        //if (n<3)return n;
        sort(p,p+n,cmp);
        int i;
        int top=0;
        for(i=0;i<n;i++)
        {
            while(top>=2&&cross(res[top-2],res[top-1],p[i])<0)
                top--;
            res[top++]=p[i];
        }
        int t=top+1;
        for(i=n-2;i>=0;i--)
        {
            while(top>=t&&cross(res[top-2],res[top-1],p[i])<0)
                top--;
            res[top++]=p[i];
        }
        /*for(i=0;i<top;i++)
            printf("%d %d
    ",res[i].x,res[i].y);*/
        return top;
    }
    int main()
    {
        int n;
        int i,j;
        //ifstream cin("A.txt");
        int __case=0;
        while(cin>>n&&n)
        {
            for(i=0;i<n;i++)
            {
                cin>>Ini[i].x>>Ini[i].y>>Ini[i].v;
                Ini[i].i=i;
            }
            sort(Ini,Ini+n,cmp1);
                //cout<<Ini[i-1].x<<Ini[i-1].y;
            int tmp=0;
            for(i=0;i<n;i++)
            {
                if(Ini[0].v==Ini[i].v)tmp++;
                else break;
            }
            point po;
            for(i=0,j=0;i<tmp;)
            {
                po=Ini[i];
                if(i<tmp-1&&Ini[i+1].x==Ini[i].x&&Ini[i+1].y==Ini[i].y)
                {
                    while(i<tmp-1&&Ini[i+1].x==Ini[i].x&&Ini[i+1].y==Ini[i].y)
                        i++;
                }
                else
                {
                    p[j++]=po;
                }
                i++;
            }
            printf("Case #%d: ",++__case);
    
            int m=Graham(p,j);
    
            memset(ans,0,sizeof(ans));
            for(i=0;i<m;i++)
            {
                //printf("%d %d %d",res[i].x,res[i].y,res[i].v);
                if(res[i].v>0)
                {
                    ans[res[i].i]=1;
                }
            }
            for(i=0;i<n;i++)
                printf("%d",ans[i]);
            printf("
    ");
        }
        return 0;
    }
    View Code

    WA:构造凸包之后去重点

    #include<stdio.h>
    #include<algorithm>
    #include<fstream>
    #include<string.h>
    #include<iostream>
    using namespace std;
    const int MAX=550;
    struct point
    {
        int x;
        int y;
        int v;
        int i;
        int tmp;
    } Ini[MAX],res[MAX];
    bool flag[MAX];
    int ans[MAX];
    bool cmp(point A,point B)
    {
        if(A.y==B.y)return A.x<B.x;
        return A.y<B.y;
    }
    bool cmp1(point A,point B)
    {
        if(A.v>B.v)return true;
        return false;
    }
    int cross(point A,point B,point C)
    {
        return (B.x-A.x)*(C.y-A.y)-(C.x-A.x)*(B.y-A.y);
    }
    int Graham(point *p,int n)
    {
        //if (n<3)return n;
        sort(p,p+n,cmp);
        memset(flag,false,sizeof(flag));
        int i;
        int top=0;
        for(i=0; i<n; i++)
        {
            while(top>=2&&cross(res[top-2],res[top-1],p[i])<0)
                top--;
    
            res[top++]=p[i];
            res[top-1].tmp=i;
        }
        for(i=0;i<top;i++)
            flag[res[i].tmp]=true;
    
        int t=top+1;
        for(i=n-2; i>=0; i--) //i>=0
        {
            while(top>=t&&cross(res[top-2],res[top-1],p[i])<0)
                top--;
            if(!flag[i])res[top++]=p[i];
            //if(i==0)top--;
        }
        /*for(i=0; i<top; i++)
            printf("$%d %d
    ",res[i].x,res[i].y);*/
        return top;
    }
    int main()
    {
        int n;
        int i,j;
        //ifstream cin("A.txt");
        int __case=0;
        while(cin>>n&&n)
        {
            for(i=0; i<n; i++)
            {
                cin>>Ini[i].x>>Ini[i].y>>Ini[i].v;
                Ini[i].i=i;
            }
            sort(Ini,Ini+n,cmp1);
            //cout<<Ini[i-1].x<<Ini[i-1].y;
            int tmp=0;
            for(i=0; i<n; i++)
            {
                if(Ini[0].v>0&&Ini[0].v==Ini[i].v)tmp++;
                else break;
            }
            int m=Graham(Ini,tmp);
            memset(ans,0,sizeof(ans));
            printf("Case #%d: ",++__case);
            point po;
            for(i=0; i<m; i++)
            {
                po=res[i];
                //printf("#%d %d %d
    ",res[i].x,res[i].y,res[i].i);
                if(i<m-1&&res[i+1].x==po.x&&res[i+1].y==po.y)
                {
                    while(i<m-1&&res[i+1].x==po.x&&res[i+1].y==po.y)
                        i++;
                }
                else
                    ans[po.i]=1;
            }
            for(i=0; i<n; i++)
                printf("%d",ans[i]);
            printf("
    ");
        }
        return 0;
    }
    View Code

    数据:

    9
    0 0 1
    0 0 1
    0 10 1
    0 10 1
    10 0 1
    10 0 1
    10 10 1
    10 10 1
    5 5 1

    构造凸包之前去掉重点,保留相同点中的一个。

    AC:

    #include<stdio.h>
    #include<algorithm>
    #include<fstream>
    #include<string.h>
    #include<iostream>
    using namespace std;
    const int MAX=550;
    struct point
    {
        int x;
        int y;
        int v;
        int i;
        int tmp;
    } Ini[MAX],res[MAX],p[MAX];
    bool flag[MAX];
    int ans[MAX];
    bool cmp(point A,point B)
    {
        if(A.y==B.y)return A.x<B.x;
        return A.y<B.y;
    }
    bool cmp1(point A,point B)
    {
        if(A.v>B.v)return true;
        if(A.v==B.v)
        {
            if(A.x<B.x)return true;
            if(A.x==B.x&&A.y<B.y)return true;
        }
        return false;
    }
    int cross(point A,point B,point C)
    {
        return (B.x-A.x)*(C.y-A.y)-(C.x-A.x)*(B.y-A.y);
    }
    int Graham(point *p,int n)
    {
        //if (n<3)return n;
        sort(p,p+n,cmp);
        memset(flag,false,sizeof(flag));
        int i;
        int top=0;
        for(i=0; i<n; i++)
        {
            while(top>=2&&cross(res[top-2],res[top-1],p[i])<0)
            {
                top--;
            }
            res[top++]=p[i];
            res[top-1].tmp=i;
        }
        for(i=0;i<top;i++)
            flag[res[i].tmp]=true;
    
        int t=top+1;
        for(i=n-2; i>=0; i--) //i>=0
        {
            while(top>=t&&cross(res[top-2],res[top-1],p[i])<0)
                top--;
            if(!flag[i])res[top++]=p[i];
            //if(i==0)top--;
        }
        /*for(i=0; i<top; i++)
            printf("$%d %d
    ",res[i].x,res[i].y);*/
        return top;
    }
    int main()
    {
        int n;
        int i,j;
        //ifstream cin("A.txt");
        int __case=0;
        while(cin>>n&&n)
        {
            for(i=0; i<n; i++)
            {
                cin>>Ini[i].x>>Ini[i].y>>Ini[i].v;
                Ini[i].i=i;
            }
            sort(Ini,Ini+n,cmp1);
            //cout<<Ini[i-1].x<<Ini[i-1].y;
            int tmp=0;
            for(i=0; i<n; i++)
            {
                if(Ini[0].v>0&&Ini[0].v==Ini[i].v)tmp++;
                else break;
            }
    
            memset(ans,0,sizeof(ans));
            point po;
            for(i=0,j=0;i<tmp;i++)
            {
                po=Ini[i];
                //flag=1;
                if(i<tmp-1&&Ini[i+1].x==po.x&&Ini[i+1].y==po.y)
                {
                    //flag=0;
                    while(i<tmp-1&&Ini[i+1].x==po.x&&Ini[i+1].y==po.y)
                    {
                        ans[Ini[i].i]=-1;
                        i++;
                    }
                    ans[Ini[i].i]=-1;
                }
                p[j++]=po;
            }
            int m=Graham(p,j);
    
            printf("Case #%d: ",++__case);
            for(i=0; i<m; i++)
            {
                if(!ans[res[i].i])ans[res[i].i]=1;
            }
            for(i=0; i<n; i++)
            {
                if(ans[i]==1)printf("1");
                else printf("0");
            }
            printf("
    ");
        }
        return 0;
    }
    View Code
  • 相关阅读:
    Spring boot和Spring cloud对应版本兼容问题
    关于 Workbench中 pk,nn,uq,bin,un,zf,ai 的解释
    WebServiceUtil
    POI 导出Excel工具类
    初步了解HTTP协议
    性能测试从零开始-LoadRunner入门
    创新券功能介绍
    Loadrunner 11安装和破解
    《追风筝的人》读后感
    h5学习-webstorm工具的激活
  • 原文地址:https://www.cnblogs.com/XDJjy/p/3915259.html
Copyright © 2011-2022 走看看