一个凸包不稳定是指能在原来的凸包上加一个点,得到更大的凸包
题目
那么要想成为一个稳定凸包,就必须要满足凸包的每条边至少有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;
}