码迷,mamicode.com
首页 > 其他好文 > 详细

poj1228--稳定凸包

时间:2016-07-29 21:31:21      阅读:176      评论:0      收藏:0      [点我收藏+]

标签:

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

 

思路:先求出题目给出的点的凸包,看看在凸包的每条边内(不包括端点)有没有点,若有,则这条边是确定的,若没有,则这条边不确定,直接输出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;
}

 

poj1228--稳定凸包

标签:

原文地址:http://www.cnblogs.com/gjghfd/p/5719650.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!