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

POJ 1228 /// 稳定凸包

时间:2018-09-15 01:20:37      阅读:159      评论:0      收藏:0      [点我收藏+]

标签:view   span   技术分享   hid   lap   name   std   a+b   can   

题目大意:

t个测试用例

每次给定一个n

接下来给定n个点

判断这n个点组成的多边形是不是一个稳定凸包

 

稳定凸包就是一条边上有至少三个点 这样但凡多出一个点 都会形成凹多边形

可以看下这个讲解https://www.cnblogs.com/xdruid/archive/2012/06/20/2555536.html

那么只要求凸包 然后判断一条边上是否有三个以上的点

技术分享图片
#include <cstdio>
#include <algorithm>
#include <cmath>
#define INF 0x3f3f3f3f
using namespace std;

const double eps=1e-10;
double add(double a,double b) {
    if(abs(a+b)<eps*(abs(a)+abs(b))) return 0;
    return a+b;
}
struct P {
    double x,y;
    P(){};
    P(double _x,double _y):x(_x),y(_y){};
    P operator - (P p) {
        return P(add(x,-p.x),add(y,-p.y)); }
    P operator + (P p) {
        return P(add(x,p.x),add(y,p.y)); }
    P operator * (double d) {
        return P(x*d,y*d); }
    double dot(P p) {
        return add(x*p.x,y*p.y); }
    double det(P p) {
        return add(x*p.y,-y*p.x); }
}p2[1005], p3[1005];
int n, k;
bool cmp(P a,P b) {
    if(a.x==b.x) return a.y<b.y;
    return a.x<b.x;
}
void andrew()
{
    sort(p2,p2+n,cmp);
    k=0;
    // 求凸包时 <= 应改成 <,将同一条边上的也加入
    for(int i=0;i<n;i++) {
        while(k>1 && (p3[k-1]-p3[k-2]).det(p2[i]-p3[k-1])<0)
            k--;
        p3[k++]=p2[i];
    }
    for(int i=n-2,t=k;i>=0;i--) {
        while(k>t && (p3[k-1]-p3[k-2]).det(p2[i]-p3[k-1])<0)
            k--;
        p3[k++]=p2[i];
    }
    if(n>1) k--;
}
bool judge()
{
    for(int i=0;i<k;i++) {
        int j=i; // 起点为 j
        while((p3[(j+1)%n]-p3[j]).det(p3[(j+2)%n]-p3[(j+1)%n])==0)
            j++; // 判断点j+1是否在j到j+2的边上
        if(j>i) i=j; // 只要有一点在边上 就满足至少三个 i转到下一条边的起点
        else return 0; // 否则不满三个 返回0
    }
    return 1;
}

int main()
{
    int t; scanf("%d",&t);
    while(t--) {
        scanf("%d",&n);
        for(int i=0;i<n;i++)
            scanf("%lf%lf",&p2[i].x,&p2[i].y);

        if(n<6) {
            printf("NO\n"); continue;
        } // 稳定的三角形凸包至少6个点
        andrew();
        if(judge()) printf("YES\n");
        else printf("NO\n");
    }

    return 0;
}
View Code

 

POJ 1228 /// 稳定凸包

标签:view   span   技术分享   hid   lap   name   std   a+b   can   

原文地址:https://www.cnblogs.com/zquzjx/p/9649631.html

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