题目大意
grandfather给k一块凸包的土地,有钉子钉在凸包的边上,现在其中一些钉子掉掉了,判断K是否能根据剩下的钉子判断出原来这边凸包的土地,能输出YES 不能输出NO
思路
如果根据剩余的点作出的凸包上的每一条边除两边端点意外还有多余的点。那么就是YES,
注意:
有可能只有一条边,那么一定是NO;
// Time 16ms; Memory 272K
#include<iostream> #include<algorithm> using namespace std; int n; typedef struct point { double x,y; point(double xx=0,double yy=0):x(xx),y(yy){} }vector; point p[1010],ch[1010]; bool operator < (point a,point b) { return a.x<b.x || (a.x==b.x && a.y<b.y); } vector operator - (point a,point b) { return vector(a.x-b.x,a.y-b.y); } double cross(vector a,vector b) { return a.x*b.y-a.y*b.x; } int graph() { int k,m=0,i; for(i=0;i<n;i++) { while(m>1 && cross(ch[m-1]-ch[m-2],p[i]-ch[m-2])<0) m--; ch[m++]=p[i]; } k=m; for(i=n-2;i>=0;i--) { while(m>k && cross(ch[m-1]-ch[m-2],p[i]-ch[m-2])<0) m--; ch[m++]=p[i]; } if(n>1) m--; return m; } int main() { int i,t,m; int a,b; cin>>t; while(t--) { cin>>n; for(i=0;i<n;i++) { cin>>p[i].x>>p[i].y; } sort(p,p+n); m=graph(); a=0;b=0; for(i=0;i<m;i++) { if(cross(ch[(i+1)%m]-ch[i],ch[(i+2)%m]-ch[i])==0) a=1; else if(a) { a=0;b=1; } else break; } if(i==m && b) cout<<"YES"<<endl; else cout<<"NO"<<endl; } return 0; }