poj1228--稳定凸包

时间:2021-09-05 01:40:17

题目大意:给你一个凸包上的某些点(可能在凸包内),询问是否能确定这个凸包。

思路:先求出题目给出的点的凸包,看看在凸包的每条边内(不包括端点)有没有点,若有,则这条边是确定的,若没有,则这条边不确定,直接输出NO。这里用Andrew求凸包。

代码如下:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
struct point{
double x,y;
point(double x=,double y=):x(x),y(y){}
}a[],ch[];
point operator - (point a,point b){
return point(a.x-b.x,a.y-b.y);
}
int i,j,k,n,m,t;
double cross(point a,point b){
return a.x*b.y-a.y*b.x;
}
bool cmp(point a,point b){
return a.x<b.x||(a.x==b.x&&a.y<b.y)?:;
}
bool check(point a,point b){
return a.x!=b.x||a.y!=b.y?:;
}
int main()
{
scanf("%d",&t);
for(int p=;p<t;p++){
m=;
scanf("%d",&n);
for(i=;i<=n;i++)scanf("%lf%lf",&a[i].x,&a[i].y);
if(n<){
printf("NO\n");
continue;
}
sort(a+,a+n+,cmp);
for(i=;i<=n;i++){
while(m>&&cross(ch[m]-ch[m-],a[i]-ch[m-])<=)m--;
ch[++m]=a[i];
}
k=m;
for(i=n-;i>=;i--){
while(m>k&&cross(ch[m]-ch[m-],a[i]-ch[m-])<=)m--;
ch[++m]=a[i];
}
for(i=;i<m;i++){
for(j=;j<=n;j++)
if(check(ch[i],a[j])&&check(ch[i+],a[j]))
if(((a[j].x>=ch[i].x&&a[j].x<=ch[i+].x)||(a[j].x<=ch[i].x&&a[j].x>=ch[i+].x))&&!cross(ch[i+]-ch[i],a[j]-ch[i]))break;
if(j==n+)break;
}
if(i<m)printf("NO\n");else printf("YES\n");
}
return ;
}