题目链接
题目大意:给你n个点,让你确定这n个点围成的凸包是否可以唯一确定一个凸包。
首先凸包分为稳定凸包和纯净凸包,是看这篇博客才知道的。点这里
这个题就是要让你判断这些点求出来的凸包是否是稳定凸包。稳定凸包上每条边都至少有三个点,为什么呢?因为如果少于三个点是两个点,那么在这条边外面再加入一个点就可以形成一个更大的凸包,原来的凸包是不稳定的。(注意题目中说了输入的点都是凸包上的点)。所以如果有一条边没有至少三点共线,则可通过加点而确定更大凸包,故无法由输入点唯一确定边界。
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<queue>
#include<map>
#include<vector>
using namespace std;
typedef long long ll;
const double eps=1e-8;
const double pi=acos(-1.0);
const int inf=0x3f3f3f3f;
const int N=1e4+10;
int sgn(double x)
{
if(fabs(x)<eps) return 0;
return x>0?1:-1;
}
struct Point
{
double x,y;
Point (double x=0,double y=0):x(x),y(y){
}
Point operator - (Point a){
return Point(x-a.x,y-a.y);}
bool operator < (const Point &a)const{
return sgn(x-a.x)<0||(sgn(x-a.x)==0&&sgn(y-a.y)<0);
}
bool operator == (const Point &a) const {
return sgn(x-a.x)==0&&sgn(y-a.y)==0;
}
};
double cross(Point a,Point b)
{
return a.x*b.y-a.y*b.x;
}
Point p[N],ch[N];
int Convexhull(Point *p,int n,Point *ch)
{
sort(p,p+n);
n=unique(p,p+n)-p;
int m=0;
for(int i=0;i<n;i++){
while(m>1&&sgn(cross(ch[m-1]-ch[m-2],p[i]-ch[m-2]))<0) m--;
ch[m++]=p[i];
}
int k=m;
for(int i=n-2;i>=0;i--){
while(m>k&&sgn(cross(ch[m-1]-ch[m-2],p[i]-ch[m-2]))<0) m--;
ch[m++]=p[i];
}
if(n>1) m--;
return m;
}
bool judge(Point *p,int n)
{
for(int i=1;i<n;i++)
{
if(cross(p[i]-p[i-1],p[(i+1)%n]-p[i])!=0&&cross(p[(i+1)%n]-p[i],p[(i+2)%n]-p[(i+1)%n])!=0)
return false;
}
return true;
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
int n;
scanf("%d",&n);
for(int i=0;i<n;i++){
scanf("%lf%lf",&p[i].x,&p[i].y);
}
if(n<6){
printf("NO\n");
continue;
}
int v=Convexhull(p,n,ch);
bool ans=judge(ch,v);
printf(ans?"YES\n":"NO\n");
}
return 0;
}