官方解题报告:http://blog.sina.com.cn/s/blog_a19ad7a10102uzj7.html
计算几何长知识,凸包中>是包括了凸包边上的点,>=是不包括边上的点,两种凸包的点数可能不同的。还有,传入凸包的点集不能有重复的点。
1 #include<cstdio> 2 #include<cstring> 3 #include<cmath> 4 #include<algorithm> 5 #include<map> 6 #define mt(a,b) memset(a,b,sizeof(a)) 7 using namespace std; 8 const double eps=1e-8; 9 const int M=512; 10 struct point{ 11 int x,y,id; 12 }p[M],res[M]; 13 map<point,int> mp; 14 bool operator < (const point &l, const point &r) { 15 return l.y < r.y || (fabs(l.y- r.y)<eps && l.x < r.x); 16 } 17 class ConvexHull { //凸包 18 bool mult(point sp, point ep, point op) {// >包括凸包边上的点,>=不包括 19 return (sp.x - op.x) * (ep.y - op.y)> (ep.x - op.x) * (sp.y - op.y); 20 } 21 public: 22 int graham(int n,point p[],point res[]) {//多边形点个数和点数组,凸包存res 23 sort(p, p + n); 24 if (n == 0) return 0; 25 res[0] = p[0]; 26 if (n == 1) return 1; 27 res[1] = p[1]; 28 if (n == 2) return 2; 29 res[2] = p[2]; 30 int top=1; 31 for (int i = 2; i < n; i++) { 32 while (top && mult(p[i], res[top], res[top-1])) top--; 33 res[++top] = p[i]; 34 } 35 int len = top; 36 res[++top] = p[n - 2]; 37 for (int i = n - 3; i >= 0; i--) { 38 while (top!=len && mult(p[i], res[top],res[top-1])) top--; 39 res[++top] = p[i]; 40 } 41 return top; // 返回凸包中点的个数 42 } 43 } gx; 44 int v[M]; 45 bool ans[M]; 46 int main(){ 47 int n,cas=1; 48 while(~scanf("%d",&n),n){ 49 int big=0; 50 for(int i=0;i<n;i++){ 51 scanf("%d%d%d",&p[i].x,&p[i].y,&v[i]); 52 p[i].id=i; 53 big=max(big,v[i]); 54 } 55 printf("Case #%d: ",cas++); 56 if(!big){ 57 for(int i=0;i<n;i++){ 58 printf("0"); 59 } 60 puts(""); 61 continue; 62 } 63 int lp=0; 64 mp.clear(); 65 for(int i=0;i<n;i++){ 66 if(v[i]==big){ 67 if(!mp[p[i]]){ 68 p[lp++]=p[i]; 69 } 70 mp[p[i]]++; 71 } 72 } 73 int lr=gx.graham(lp,p,res); 74 mt(ans,0); 75 for(int i=0;i<lr;i++){ 76 if(mp[res[i]]==1){ 77 ans[res[i].id]=true; 78 } 79 } 80 for(int i=0;i<n;i++){ 81 printf("%d",ans[i]); 82 } 83 puts(""); 84 } 85 return 0; 86 }