Grandpa's Estate POJ - 1228 - 稳定凸包

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

题目
那么要想成为一个稳定凸包,就必须要满足凸包的每条边至少有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\n");
			return;
		}
	}
	printf("YES\n");
}
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\n");
		else hull();
	}
	return 0;
}

猜你喜欢

转载自www.cnblogs.com/Emcikem/p/12984172.html