Grandpa's Estate POJ

一个凸包不稳定是指能在原来的凸包上加一个点,得到更大的凸包

题目
那么要想成为一个稳定凸包,就必须要满足凸包的每条边至少有3个点

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
using namespace std;
const int N = 1e5 + 5;
const double eps = 1e-6;
struct Point{
    double x, y;
}p[N], s[N];
int n, cnt;
double Cross(Point a1, Point a2, Point b1, Point b2){//外积
    return (a2.x - a1.x) * (b2.y - b1.y) - (a2.y - a1.y) * (b2.x - b1.x);
}
double dis(Point p1, Point p2){
    return sqrt((p2.x - p1.x) * (p2.x - p1.x) + (p2.y - p1.y) * (p2.y - p1.y));
}
bool cmp(Point p1, Point p2){
    double tmp = Cross(p[1], p1, p[1], p2);
    if(tmp > 0) return 1;
    if(tmp == 0 && dis(p[1], p1) < dis(p[1], p2)) return 1;
    return 0;
}
void hull(){
    sort(p + 2, p + n + 1, cmp);
    s[1] = p[1];
    s[2] = p[2];
    cnt = 2;
    for(int i = 3; i <= n; i++){
        while(cnt > 1 && Cross(s[cnt - 1], s[cnt], s[cnt], p[i]) < 0)
            cnt--;
        s[++cnt] = p[i];
    }
    s[cnt + 1] = p[1];
    s[0] = s[cnt];
    for(int i = 1; i < cnt; i++){
        if(Cross(s[i - 1], s[i], s[i - 1], s[i + 1]) != 0
            && Cross(s[i], s[i + 1], s[i], s[i + 2]) != 0){
            printf("NO
");
            return;
        }
    }
    printf("YES
");
}
int main(){
    int t;
    scanf("%d", &t);
    while(t--){
        scanf("%d", &n);
        for(int i = 1; i <= n; i++){
            scanf("%lf%lf", &p[i].x, &p[i].y);
            if(p[1].y > p[i].y || (p[1].y == p[i].y && p[1].x > p[i].x))
                swap(p[1], p[i]);
        }
        if(n < 6) printf("NO
");
        else hull();
    }
    return 0;
}
原文地址:https://www.cnblogs.com/Emcikem/p/12984172.html