• hdu 4946 Area of Mushroom(凸包)


    链接:http://acm.hdu.edu.cn/showproblem.php?pid=4946

    Area of Mushroom

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
    Total Submission(s): 1896    Accepted Submission(s): 452


    Problem Description
    Teacher Mai has a kingdom with the infinite area.

    He has n students guarding the kingdom.

    The i-th student stands at the position (xi,yi), and his walking speed is vi.

    If a point can be reached by a student, and the time this student walking to this point is strictly less than other students, this point is in the charge of this student.

    For every student, Teacher Mai wants to know if the area in the charge of him is infinite.
     
    Input
    There are multiple test cases, terminated by a line "0".

    For each test case, the first line contains one integer n(1<=n<=500).

    In following n lines, each line contains three integers xi,yi,vi(0<=|xi|,|yi|,vi<=10^4).
     
    Output
    For each case, output "Case #k: s", where k is the case number counting from 1, and s is a string consisting of n character. If the area in the charge of the i-th student isn't infinite, the i-th character is "0", else it's "1".
     
    Sample Input
    3
    0 0 3
    1 1 2
    2 2 1
    0
     
    Sample Output
    Case #1: 100
     
    Source

    -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

    直接引用这里了:http://blog.csdn.net/hcbbt/article/details/38582243

    题意: 
    给定n个人,每个人的坐标和移动速度v,若对于某个点,只有 x 能最先到达(即没有人能比x先到这个点或者同时到这个点),则这个点称作被x占有,若有人能占有无穷大的面积 则输出1 ,否则输出0。

    分析: 
    到最后只有速度最大的点才有可能获得无穷大的面积。所以只要考虑速度最大的点。 
    很明显,只有这些点的凸包边上的点才能获得无穷大的面积。 
    所以求凸包边上的点就行了。

    有几个要注意的坑就是: 
    1. 如果有点(x,y,v)都相同,那这个点是无法占领无限大的,但是不能不考虑这个点进行凸包,因为这个点会对其他点产生影响。 
    2. 如果最大速度为0,那么每个点都不会动,所以就不用进行凸包了。

    ====================================================

    多校的题目质量确实高,就这题来说,设了几个坑,最大速度为零的情况,以及三点共线的情况,还有三点在边界上的情况

    凸包有两种构建方法,一个是用极角排序,再循环一次

    二是直接坐标排序,循环两次

    但是第一种情况,对于三点在边界上的情况会少了最后一个点

    这也是为什么网上的题解差不多都是第二种方法的原因,第一种方法,如果想用的话,必须先建凸包,

    再判断是否在凸包的两点之间那条线上,在的话就保留,当然,会费些时间

    ----------------------------------------------------------------------------------

    第二种方法建凸包:

      1 #include <stdio.h>
      2 #include <string.h>
      3 #include <stdlib.h>
      4 #include <math.h>
      5 #include <iostream>
      6 #include <algorithm>
      7 
      8 using namespace std;
      9 #define MAXX 1110
     10 #define eps 1e-8
     11 
     12 typedef struct point
     13 {
     14     double x;
     15     double y;
     16     int v;
     17     int id;
     18 } point;
     19 
     20 bool dy(double x,double y)
     21 {
     22     return x>y+eps;
     23 }
     24 bool xy(double x,double y)
     25 {
     26     return x<y-eps;
     27 }
     28 bool dyd(double x,double y)
     29 {
     30     return x>y-eps;
     31 }
     32 bool xyd(double x,double y)
     33 {
     34     return x<y+eps;
     35 }
     36 bool dd(double x,double y)
     37 {
     38     return fabs(x-y)<eps;
     39 }
     40 
     41 double crossProduct(point a,point b,point c)
     42 {
     43     return (a.x-c.x)*(b.y-c.y)>(b.x-c.x)*(a.y-c.y);
     44 }
     45 double dist(point a,point b)
     46 {
     47     return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
     48 }
     49 
     50 point p[MAXX];
     51 point stk[MAXX];
     52 int top;
     53 
     54 bool cmp(point a,point b)
     55 {
     56     if( dd(a.y,b.y))
     57         return xy(a.x,b.x);
     58     return xy(a.y,b.y);
     59 }
     60 
     61 void Graham(int n)
     62 {
     63     top=1;
     64     sort(p,p+n,cmp);
     65     if(n == 0)
     66     {
     67         top=-1;
     68         return ;
     69     }
     70     stk[0]=p[0];
     71     if(n == 1)
     72     {
     73         top=0;
     74         return;
     75     }
     76     stk[1]=p[1];
     77     if(n == 2)
     78     {
     79         top=1;
     80         return;
     81     }
     82     stk[2]=p[2];
     83     for(int i=2; i<n; i++)
     84     {
     85         while(top && crossProduct(p[i],stk[top],stk[top-1]))
     86             top--;
     87         stk[++top]=p[i];
     88     }
     89     int len=top;
     90     stk[++top]=p[n-2];
     91     for(int i=n-3; i>=0; i--)
     92     {
     93         while(top != len && crossProduct(p[i],stk[top],stk[top-1]))
     94             top--;
     95         stk[++top]=p[i];
     96     }
     97 }
     98 
     99 int main()
    100 {
    101     int i,j,n,m;
    102     int cas=1;
    103 
    104     while(scanf("%d",&n)!=EOF && n)
    105     {
    106         point tmp[MAXX];
    107         int mark[MAXX];
    108         int maxx=0;
    109         memset(mark,0,sizeof(mark));
    110 
    111         for(i=0; i<n ; i++)
    112         {
    113 
    114             scanf("%lf%lf%d",&tmp[i].x,&tmp[i].y,&tmp[i].v);
    115             if(maxx < tmp[i].v)
    116             {
    117                 maxx=tmp[i].v;
    118             }
    119             tmp[i].id=i;
    120         }
    121         if(maxx == 0)
    122         {
    123 
    124             printf("Case #%d: ",cas++);
    125             for(i=0; i<n; i++)
    126                 printf("%d",mark[i]);
    127             printf("
    ");
    128             continue;
    129         }
    130         int id[MAXX];
    131         memset(id,0,sizeof(id));
    132         for(i=0; i<n; i++)
    133         {
    134 
    135             for(j=i+1; j<n; j++)
    136             {
    137 
    138                 if(tmp[i].x == tmp[j].x && tmp[i].y == tmp[j].y && tmp[i].v == tmp[j].v)
    139                 {
    140 
    141                     tmp[i].v=0;
    142                     id[i]=id[j]=-1;
    143                 }
    144             }
    145         }
    146         int ss=0;
    147         for(i=0; i<n; i++)
    148         {
    149 
    150             if(maxx == tmp[i].v)
    151             {
    152 
    153                 p[ss++] = tmp[i];//can??
    154             }
    155         }
    156         Graham(ss);
    157         for(i=0; i<=top; i++)
    158         {
    159 
    160             if(id[stk[i].id] != -1)
    161             {
    162 
    163                 id[stk[i].id] = 1;
    164             }
    165         }
    166         printf("Case #%d: ",cas++);
    167         for(i=0; i<n; i++)
    168             printf("%d",id[i]>0?1:0);
    169         printf("
    ");
    170     }
    171     return 0;
    172 }
    173 
    174 /*
    175    5
    176   0 0 6
    177   3 3 6
    178   1 1 6
    179   0 3 6
    180   3 0 6
    181   Case #1: 11011
    182   9
    183   0 0 3
    184   0 1 3
    185   0 2 3
    186   1 0 3
    187   1 1 3
    188   1 2 3
    189   2 0 3
    190   2 1 3
    191   2 2 3
    192   Case #2: 111101111
    193     3
    194     0 0 3
    195     1 1 2
    196     2 2 1
    197   Case #3: 100
    198   3
    199   0 0 3
    200   0 0 3
    201   0 0 3
    202   Case #4: 000
    203   8
    204   1 1 3
    205   2 1 3
    206   3 1 3
    207   3 2 3
    208   2 2 3
    209   1 2 3
    210   1 3 3
    211   3 3 3
    212   Case #5: 11110111
    213   4
    214   0 0 3
    215   0 3 3
    216   3 0 3
    217   1 1 3
    218   Case #6: 1110
    219   6
    220   0 0 1
    221   -1 0 1
    222   1 0 1
    223   0 1 1
    224   0 -1 1
    225   0 -1 1
    226   Case #7: 011100
    227 */
    View Code

    第一种方法建凸包但wa的:

      1 #include <stdio.h>
      2 #include <string.h>
      3 #include <stdlib.h>
      4 #include <math.h>
      5 #include<iostream>
      6 #include <algorithm>
      7 
      8 using namespace std;
      9 #define MAXX 1110
     10 #define eps 1e-8
     11 
     12 typedef
     13 
     14 struct point
     15 {
     16 
     17     double x;
     18     double y;
     19     int v;
     20     int id;
     21 } point;
     22 
     23 bool dy(double x,double y)
     24 {
     25     return x>y+eps;
     26 }
     27 bool xy(double x,double y)
     28 {
     29     return x<y-eps;
     30 }
     31 bool dyd(double x,double y)
     32 {
     33     return x>y-eps;
     34 }
     35 bool xyd(double x,double y)
     36 {
     37     return x<y+eps;
     38 }
     39 bool dd(double x,double y)
     40 {
     41     return fabs(x-y)<eps;
     42 }
     43 
     44 double crossProduct(point a,point b,point c)
     45 {
     46 
     47     return (c.x-a.x)*(b.y-a.y)-(c.y-a.y)*(b.x-a.x);
     48 }
     49 double dist(point a,point b)
     50 {
     51     return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
     52 }
     53 
     54 point p[MAXX];
     55 point stk[MAXX];
     56 int top;
     57 
     58 bool cmp(point a,point b)
     59 {
     60 
     61     double len=crossProduct(p[0],a,b);
     62     if(dd(len,0.0))
     63     {
     64 
     65         return xy(dist(p[0],a),dist(p[0],b));
     66     }
     67     return xy(len ,0.0);
     68 }
     69 
     70 
     71 
     72 int Graham(int n)
     73 {
     74 
     75     int tmp=0;
     76     if(n<2) return 0;
     77     for(int i=1; i<n; i++)
     78     {
     79 
     80         if(xy(p[i].x,p[tmp].x) || dd(p[i].x,p[tmp].x) && xy(p[i].y,p[tmp].y))
     81             tmp=i;
     82     }
     83     swap(p[0],p[tmp]);
     84     sort(p,p+n,cmp);
     85     top=1;
     86     stk[0]=p[0];
     87     stk[1]=p[1];
     88     for(int i=2; i<n; i++)
     89     {
     90         while(top && xy(crossProduct(stk[top],stk[top-1],p[i]),0.0))
     91             top--;
     92         stk[++top]=p[i];//会少一个点
     93     }
     94     /*int len=top;
     95     stk[++top] = p
     96 
     97     [n-2];
     98     for(int i=n-3; i>=0; i--)
     99     {
    100         while(top != len && xy(crossProduct(stk
    101 
    102     [top],stk[top-1],p[i]),0.0))
    103             top--;
    104         stk[++top] = p[i];
    105     }*/
    106 
    107 
    108     return top;
    109 }
    110 
    111 int main()
    112 {
    113 
    114     int i,j,n,m;
    115     int cas=1;
    116 
    117     while(scanf("%d",&n)!=EOF && n)
    118     {
    119         point tmp[MAXX];
    120         int mark[MAXX];
    121         int maxx=0;
    122         memset(mark,0,sizeof(mark));
    123         for(i=0; i<n ; i++)
    124         {
    125 
    126             scanf("%lf%lf%d",&tmp[i].x,&tmp[i].y,&tmp[i].v);
    127             if(maxx < tmp[i].v)
    128             {
    129                 maxx=tmp[i].v;
    130             }
    131             tmp[i].id=i;
    132         }
    133         if(maxx == 0)
    134         {
    135             printf("Case #%d: ",cas++);
    136             for(i=0; i<n; i++)
    137                 printf("%d",mark[i]);
    138             printf("
    ");
    139             continue;
    140         }
    141         int id[MAXX];
    142         memset(id,0,sizeof(id));
    143         for(i=0; i<n; i++)
    144         {
    145 
    146             for(j=i+1; j<n; j++)
    147             {
    148                 if(tmp[i].x == tmp[j].x && tmp[i].y == tmp[j].y &&tmp[i].v == tmp[j].v)
    149                 {
    150                     tmp[i].v=0;
    151                     id[i]=id[j]=-1;
    152                 }
    153             }
    154         }
    155         int ss=0;
    156         for(i=0; i<n; i++)
    157         {
    158             if(maxx == tmp[i].v)
    159             {
    160                 p[ss++]=tmp[i];//can??
    161             }
    162         }
    163         int top=Graham(ss);
    164         for(i=0; i<=top; i++)
    165         {
    166             if(id[stk[i].id] != -1)
    167             {
    168                 id[stk[i].id] = 1;
    169             }
    170         }
    171         printf("Case #%d: ",cas++);
    172         for(i=0; i<n; i++)
    173             printf("%d",id[i]>0?1:0);
    174         printf("
    ");
    175     }
    176     return 0;
    177 }
    178 
    179 /*
    180   5
    181   0 0 6
    182   3 3 6
    183   1 1 6
    184 
    185 
    186  0 3 6
    187   3 0 6
    188   Case #1: 11011
    189   9
    190   0 0 3
    191   0 1 3
    192   0 2 3
    193   1 0 3
    194   1 1 3
    195   1 2 3
    196   2 0 3
    197   2 1 3
    198   2
    199 
    200 2 3
    201   Case #2: 111101111
    202     3
    203     0 0 3
    204     1 1 2
    205     2 2 1
    206   Case #3: 100
    207   3
    208   0 0 3
    209   0 0 3
    210   0 0
    211 
    212 3
    213   Case #4: 000
    214   8
    215   1 1 3
    216   2 1 3
    217   3 1 3
    218   3 2 3
    219   2 2 3
    220   1 2 3
    221   1 3 3
    222   3 3 3
    223   Case #5:
    224 
    225 11110111
    226   4
    227   0 0 3
    228   0 3 3
    229   3 0 3
    230   1 1 3
    231   Case #6: 1110
    232   6
    233   0 0 1
    234   -1 0 1
    235   1 0 1
    236   0 1 1
    237   0
    238 
    239 -1 1
    240   0 -1 1
    241   Case #7: 011100
    242 */
    View Code

    网上找的第一种方法AC的:(希望原创别喷我)

      1 #include<cstdio>
      2 #include<cstring>
      3 #include<algorithm>
      4 #include<cmath>
      5 #include<vector>
      6 #include <iostream>
      7 #define EPS 1e-8
      8 #define eps 1e-8
      9 using namespace std;
     10 struct TPoint
     11 {
     12     double x,y;
     13     int id,v;
     14 }p[510],s[506],hull[510],pp[510];
     15 double cross(TPoint a, TPoint b, TPoint c) {
     16     return (b.x - a.x) * (c.y - a.y) - (c.x - a.x)*(b.y - a.y);
     17 }
     18 double dis(TPoint a,TPoint b)
     19 {
     20     return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
     21 }
     22 bool graham_cmp(const TPoint &b, const TPoint &c) {
     23     double tmp = cross(b, c, p[0]);
     24     if (tmp > EPS)
     25         return true;
     26     if (fabs(tmp) < EPS && (dis(b, p[0]) < dis(c, p[0])))
     27         return true;
     28     return false;
     29 }
     30 int graham_scan(TPoint hull[], int n) {
     31     int top, i, k = 0;
     32     for (i = 1; i < n; ++i)
     33         if ((p[k].y - p[i].y > EPS)
     34                 || (fabs(p[i].y - p[k].y) < EPS && p[k].x - p[i].x > EPS))
     35             k = i;
     36     swap(p[0], p[k]);
     37     sort(p + 1, p + n, graham_cmp);
     38     hull[0] = p[0], hull[1] = p[1], hull[2] = p[2];
     39     if (n < 3)
     40         return n;
     41     else
     42         top = 3;
     43     for (i = 3; i < n; ++i) {
     44         while (top >= 2 && cross(hull[top - 2], hull[top - 1], p[i]) < EPS)
     45             --top;
     46         hull[top++] = p[i];
     47     }
     48     return top;
     49 }
     50 bool bo[550];
     51 int ans[550];
     52 bool cmp(TPoint a,TPoint b)
     53 {
     54     return a.x<b.x-eps||(fabs(a.x-b.x)<eps&&a.y<b.y);
     55 }
     56 int main() {
     57     int ri=0,n;
     58     while(scanf("%d",&n)&&n)
     59     {
     60         int maxn=0;
     61         for(int i=0;i<n;++i)
     62             ans[i]=0;
     63         for(int i=0;i<n;++i)
     64         {
     65             scanf("%lf%lf%d",&s[i].x,&s[i].y,&s[i].v);
     66             s[i].id=i;
     67             maxn=std::max(maxn,s[i].v);
     68         }
     69         if(maxn==0)
     70         {
     71             printf("Case #%d: ",++ri);
     72             for(int i=0;i<n;++i)
     73                 printf("0");
     74             puts("");
     75             continue;
     76         }
     77         int tail=0;
     78         for(int i=0;i<n;++i)
     79         {
     80             if(s[i].v==maxn&&maxn>0)
     81             {
     82                 pp[tail]=s[i];
     83                 p[tail++]=s[i];
     84             }
     85         }
     86         sort(p,p+tail,cmp);
     87         int kk=0;
     88         for(int i=0;i<tail;++i)
     89             if(i==tail-1||fabs(p[i].x-p[i+1].x)>eps||fabs(p[i].y-p[i+1].y)>eps)
     90                 p[kk++]=p[i];
     91         int h=graham_scan(hull,kk);
     92         hull[h]=hull[0];
     93         for(int i=0;i<tail;++i)
     94         {
     95             int flag=0;
     96             for(int j=0;j<tail;++j)
     97                 if(i!=j&&fabs(pp[i].x-pp[j].x)<eps&&fabs(pp[i].y-pp[j].y)<eps)
     98                 {
     99                     flag=1;
    100                     break;
    101                 }
    102             if(flag)
    103             {
    104                 ans[pp[i].id]=0;
    105                 continue;
    106             }
    107             bool ok=false;
    108             for(int j=0;j<h;++j)
    109             {
    110                 if(fabs(cross(pp[i],hull[j],hull[j+1]))<eps)
    111                     ok=true;
    112             }
    113             if(ok)
    114                 ans[pp[i].id]=1;
    115             else
    116                 ans[pp[i].id]=0;
    117         }
    118         printf("Case #%d: ",++ri);
    119         for(int i=0;i<n;++i)
    120             printf("%d",ans[i]);
    121         puts("");
    122 
    123     }
    124 }
    View Code
  • 相关阅读:
    Python一直在找动态Cookie,恩!
    python和Ajax在一起了?真的???
    Flask网页session记住用户登录状态
    Rxjs Observable.pipe 传入多个 operators 的执行逻辑分析
    RxJs map operator 工作原理分析
    RxJs fromEvent 工作原理分析
    SAP Spartacus Reference App Structure
    SAP Spartacus RouterModule.forRoot() called twice 的错误消息
    SAP UI5 XML 视图里 label 和 text 控件文本对齐问题
    Angular 使用 Injector API 人工获取依赖注入的实例
  • 原文地址:https://www.cnblogs.com/ccccnzb/p/3917821.html
Copyright © 2020-2023  润新知