Time Limit: 1000MS | Memory Limit: 10000K | |
Total Submissions: 11990 | Accepted: 3340 |
Description
Input
Output
Sample Input
1 6 0 0 1 2 3 4 2 0 2 4 5 0
Sample Output
NO 题意:给你一堆点,这堆点本来就是某个凸包上的部分点,问你这堆点是否能确定唯一的凸包 思路:稳定凸包每条边都要有三个点,所以说在入栈的过程中在同一条直线上的点也要入栈,然后判断是否都是三点 共线就行了。。 ac代码:#include<stdio.h> #include<math.h> #include<string.h> #include<queue> #include<map> #include<vector> #define MAXN 1010 #define LL long long #define INF 0xfffffff #define mem(x) memset(x,0,sizeof(x)) #define PI acos(-1) #include<iostream> #include<algorithm> using namespace std; struct s { double x,y; }list[MAXN]; s stack[MAXN]; int top; double dis(s aa,s bb) { return sqrt(1.0*((aa.x-bb.x)*(aa.x-bb.x)+(aa.y-bb.y)*(aa.y-bb.y))); } double cross(s p0,s p1,s p2) { return (p1.x-p0.x)*(p2.y-p0.y)-(p1.y-p0.y)*(p2.x-p0.x); } bool cmp(s aa,s bb) { double num=cross(list[0],aa,bb); if(num<0||(!num&&dis(list[0],aa)>dis(list[0],bb))) return false; return true; } void graham(int n) { int i; stack[0]=list[0]; stack[1]=list[1]; top=1; for(i=2;i<n;i++) { while(top>=1&&cross(stack[top-1],stack[top],list[i])<0) top--;//共线也入栈 top++; stack[top]=list[i]; } } int main() { int n,i; int t; scanf("%d",&t); while(t--) { scanf("%d",&n); for(i=0;i<n;i++) scanf("%lf%lf",&list[i].x,&list[i].y); if(n<6) { printf("NO\n"); continue; } for(i=1;i<n;i++) { s temp; if(((list[0].y==list[i].y)&&(list[0].x>list[i].x))||list[0].y>list[i].y) { temp=list[i]; list[i]=list[0]; list[0]=temp; } } sort(list+1,list+n,cmp); graham(n); //stack[top+1]=list[0]; int bz=0; for(i=1;i<top;i++) { if((cross(stack[i-1],stack[i+1],stack[i]))!=0&&cross(stack[i],stack[i+2],stack[i+1])!=0)//判断三点共线 { bz=1; break; } } if(bz==0) printf("YES\n"); else printf("NO\n"); } return 0; }