题目链接
题意:给你n个凸包上的点,问你这些点围成的凸包是不是唯一的。
题解:
这题如果没有接触过相关套路或者习题的话,第一感觉可能是比较懵的。我的第一感觉是,完全没弄懂什么情况可以唯一确定,看了看样例,又随手话了几个凸包,感觉没画出什么样算是唯一的。
后来看了zyf2000的题解之后发现,其实只要凸包的每一条边上都有大于等于3个点就形成的凸包就是唯一的了。
据说这东西叫稳定凸包。
这样就是求完凸包叉积判断是否共线了。
代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <cstdlib>
using namespace std;
int t,n,pd,sta[10010],tp,ji,num;
double eps=1e-12;
struct Point
{
double x,y;
}a[10001];
struct Vector
{
double x,y;
};
int cmp(Point x,Point y)
{
if(x.x==y.x)
return x.y<y.y;
return x.x<y.x;
}
double chaji(Vector x,Vector y)
{
return x.x*y.y-y.x*x.y;
}
int dcmp(double x)
{
if(fabs(x)<eps)
return 0;
if(x>0)
return 1;
else
return -1;
}
int main()
{
scanf("%d",&t);
while(t--)
{
pd=0;
scanf("%d",&n);
for(int i=1;i<=n;++i)
scanf("%lf%lf",&a[i].x,&a[i].y);
if(n<=3)
{
printf("NO\n");
continue;
}
sort(a+1,a+n+1,cmp);
tp=0;
for(int i=1;i<=n;++i)
{
Vector x,y;
while(tp>1)
{
x.x=a[sta[tp]].x-a[sta[tp-1]].x;
x.y=a[sta[tp]].y-a[sta[tp-1]].y;
y.x=a[i].x-a[sta[tp-1]].x;
y.y=a[i].y-a[sta[tp-1]].y;
if(dcmp(chaji(x,y))<0)
--tp;
else
break;
}
sta[++tp]=i;
}
ji=tp;
for(int i=n-1;i>=1;--i)
{
Vector x,y;
while(tp>ji)
{
x.x=a[sta[tp]].x-a[sta[tp-1]].x;
x.y=a[sta[tp]].y-a[sta[tp-1]].y;
y.x=a[i].x-a[sta[tp-1]].x;
y.y=a[i].y-a[sta[tp-1]].y;
if(dcmp(chaji(x,y))<0)
--tp;
else
break;
}
sta[++tp]=i;
}
num=0;
ji=1;
for(int i=1;i<=tp;++i)
{
Vector x,y;
x.x=a[sta[i]].x-a[sta[ji]].x;
x.y=a[sta[i]].y-a[sta[ji]].y;
y.x=a[sta[i-1]].x-a[sta[ji]].x;
y.y=a[sta[i-1]].y-a[sta[ji]].y;
if(dcmp(chaji(x,y))==0)
++num;
else
{
if(num<3)
{
pd=1;
break;
}
num=2;
ji=i-1;
}
}
if(num<3)
pd=1;
if(pd==0)
printf("YES\n");
else
printf("NO\n");
}
return 0;
}