POJ

题目链接:https://vjudge.net/problem/POJ-1228

题意:给你一堆点,这堆点本来就是某个凸包上的部分点,问你这堆点是否能确定唯一的凸包,这种凸包叫做稳定凸包。

稳定凸包的含义:当凸包上存在一条边上的点只有端点两个点的时候,这个凸包不是稳定的,因为它可以在这条边外再引入一个点,构成一个新的凸包。

但一旦一条边上存在三个点,那么不可能再找到一个点使它扩展成一个新的凸包,否则构成的新多边形将是凹的。

思路:先根据给定的点求出凸包,在求凸包时,不需要把斜率一样位置近的点去掉。然后再看求出凸包的点上是否每条线上至少有三个点就可以了。

#include<bits/stdc++.h>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<vector>
#include<map>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
const double PI = atan(1.0)*4.;
const int maxn=200005;
struct point
{
    double x,y;
    point friend operator -(point A,point B)
    {
        return {A.x-B.x,A.y-B.y};
    }
};
struct line
{
    point x,y;
};
point p[maxn];//输入点集
point q[maxn];//凸包点集
double dis(point A,point B)//两点的距离
{
    return sqrt( (A.x-B.x)*(A.x-B.x) + (A.y-B.y)*(A.y-B.y) );
}
double chaj(point A,point B)//差积
{
    return A.x*B.y-A.y*B.x;
}
bool cmp(point A,point B)//以p[0]为起点,按差积逆时针排序
{
    double s=chaj(A-p[1],B-p[1]);
    if(s>0)
        return true;
    if(s==0)
        return dis(A,p[1])<dis(B,p[1]);
    return false;
}
int main()
{
    int T;
    cin>>T;
    while(T--)
    {
        int N;
        cin>>N;
        for(int i=1; i<=N; i++)
            cin>>p[i].x>>p[i].y;
        if(N<6)
        {
            cout<<"NO"<<endl;
            continue;
        }
        //找到最小的点
        int K=1;
        for(int i=2; i<=N; i++)
        {
            if(p[i].y<p[K].y||(p[i].y==p[K].y&&p[i].x<p[K].x))
                K=i;
        }
        swap(p[1],p[K]);

        sort(p+2,p+1+N,cmp);

        q[1]=p[1];
        q[2]=p[2];
        int len=2;//凸包点的个数
        for(int i=3; i<=N; i++)
        {
            while(len>=2&&chaj(q[len]-q[len-1],p[i]-q[len-1])<0)
                len--;
            q[++len]=p[i];
        }
        q[++len]=q[1];
        int flag=1;
        for(int i=3;i<len;i++)
        {
            if(chaj(q[i-1]-q[i-2],q[i]-q[i-1])!=0&&chaj(q[i]-q[i-1],q[i+1]-q[i])!=0)
                flag=0;
        }
        if(flag)
            cout<<"YES"<<endl;
        else
            cout<<"NO"<<endl;
    }
}
原文地址:https://www.cnblogs.com/zcb123456789/p/13809405.html