poj1228 [ SDOI2009 ] --稳定凸包

来源:互联网 发布:php开发ide排行榜 编辑:程序博客网 时间:2024/05/22 03:52
题目大意:给你一个凸包上的某些点(可能在凸包内),询问是否能确定这个凸包。

 

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

 

代码如下:

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

 

原创粉丝点击