链接: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
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.
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).
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
直接引用这里了:http://blog.csdn.net/hcbbt/article/details/38582243
题意:
给定n个人,每个人的坐标和移动速度v,若对于某个点,只有 x 能最先到达(即没有人能比x先到这个点或者同时到这个点),则这个点称作被x占有,若有人能占有无穷大的面积 则输出1 ,否则输出0。
分析:
到最后只有速度最大的点才有可能获得无穷大的面积。所以只要考虑速度最大的点。
很明显,只有这些点的凸包边上的点才能获得无穷大的面积。
所以求凸包边上的点就行了。
有几个要注意的坑就是:
1. 如果有点(x,y,v)都相同,那这个点是无法占领无限大的,但是不能不考虑这个点进行凸包,因为这个点会对其他点产生影响。
2. 如果最大速度为0,那么每个点都不会动,所以就不用进行凸包了。
====================================================
多校的题目质量确实高,就这题来说,设了几个坑,最大速度为零的情况,以及三点共线的情况,还有三点在边界上的情况
凸包有两种构建方法,一个是用极角排序,再循环一次
二是直接坐标排序,循环两次
但是第一种情况,对于三点在边界上的情况会少了最后一个点
这也是为什么网上的题解差不多都是第二种方法的原因,第一种方法,如果想用的话,必须先建凸包,
再判断是否在凸包的两点之间那条线上,在的话就保留,当然,会费些时间
----------------------------------------------------------------------------------
第二种方法建凸包:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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("\n"); 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("\n"); 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 */
第一种方法建凸包但wa的:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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("\n"); 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("\n"); 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 */
网上找的第一种方法AC的:(希望原创别喷我)
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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 }