想看更多的解题报告:http://blog.csdn.net/wangjian8006/article/details/7870410
转载请注明出处:http://blog.csdn.net/wangjian8006
题目大意:原本有一些点围成了一个凸多边形,你不知道原来是什么样子的,现在又 给出一些点,确保这些点都是凸包上的点(不会在以前的凸包的里面), 现在问你这些点围成的形状是否可以确定原来那些点围成的凸多边形
解题思路:由于我们知道现在给的点全是凸包上的点,所以我们看现在的这个凸包的【顶点】中间有没有其他的点,如果至少有一点的话,那么这条边就是确定的了,不会再有改变。
但是如果没有其他点,那么两个顶点是不能确定原来的那个凸多边形的形状的,因为两个点之间以前还可以存在某些点没在这条边上。
所以我们只需要将给的凸包点算出凸包顶点,然后再判断两相邻顶点之间有没其他点就可以了
/* Memory 188K Time 16MS */ #include <stdio.h> #include <math.h> #include <stdlib.h> #define MAXV 1010 #define INF 1e8 struct Point{ double x,y; }point[MAXV],tmp; int n,d[MAXV],dtop; double distance(double x1,double y1,double x2,double y2){ double dis=(x1-x2)*(x1-x2)+(y1-y2)*(y1-y2); return sqrt(dis); } double chaji(struct Point a1,struct Point b1,struct Point a2,struct Point b2){ //求<a1,b1>向量和<a2,b2>向量的叉积 double x1=b1.x-a1.x; double y1=b1.y-a1.y; double x2=b2.x-a2.x; double y2=b2.y-a2.y; return x1*y2-x2*y1; } int cmp(const void *p1,const void *p2){ struct Point *a=(struct Point *)p1; struct Point *b=(struct Point *)p2; double flag=chaji(point[0],*a,point[0],*b); if(flag>0) return -1; else if(!flag && distance((a->x),(a->y),point[0].x,point[0].y)<distance((b->x),(b->y),point[0].x,point[0].y)) return -1; return 1; } int findminp(){ int i,v; double ymin=INF,xmin=INF; for(i=0;i<n;i++) if(point[i].y<ymin) v=i,ymin=point[i].y; for(i=0;i<n;i++) if(point[i].y==ymin && point[i].x<xmin) v=i,xmin=point[i].x; return v; } void graham(){ int i; dtop=0; d[dtop++]=0; d[dtop++]=1; for(i=2;i<n;i++){ while(chaji(point[d[dtop-2]],point[d[dtop-1]],point[d[dtop-1]],point[i])<0) dtop--; d[dtop++]=i; } } int main(){ int t,h,i,j,flag,sum; scanf("%d",&t); while(t--){ scanf("%d",&n); for(i=0;i<n;i++) scanf("%lf%lf",&point[i].x,&point[i].y); if(n<=5) {printf("NO\n");continue;} h=findminp(); tmp=point[0]; point[0]=point[h]; point[h]=tmp; qsort(point+1,n-1,sizeof(point[0]),cmp); graham(); //求出凸包 flag=1; //看凸包上【顶点】的中间有没有其他点,如果有一条没有就是NO sum=0; for(i=1;i<dtop;i++){ for(j=0;j<n;j++) if(j!=d[i] && j!=d[i-1] && !chaji(point[d[i-1]],point[d[i]],point[d[i-1]],point[j])){ break; } if(j==n) sum++; } for(j=0;j<n;j++) if(j!=d[0] && j!=d[i-1] && !chaji(point[d[0]],point[d[i-1]],point[d[0]],point[j])){ break; } if(j==n) sum++; if(sum>0) flag=0; if(flag) printf("YES\n"); else printf("NO\n"); } return 0; }