poj1228
稳定凸包
即每条边上至少有3个点即可。。
#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <queue>
using namespace std;
const int MAXN = 1e3 + 5;
const double EPS = 1e-6;
const int INF = 0x7fffffff;
struct Point
{
Point() {}
Point(double _x, double _y): x(_x), y(_y) {}
double getDis(Point rhs)
{
double xx = rhs.x - x;
double yy = rhs.y - y;
return sqrt(xx * xx + yy * yy);
}
void input()
{
scanf("%lf%lf", &x, &y);
}
double x, y;
};
Point operator -(Point lhs, Point rhs)
{
Point ret = Point(rhs.x - lhs.x, rhs.y - lhs.y);
return ret;
}
double operator ^(Point lhs, Point rhs)
{
double ret = lhs.x * rhs.y - lhs.y * rhs.x;
return ret;
}
Point point[MAXN];
Point src;
int n;
bool cmp(Point &a, Point &b)
{
double temp = (a - src) ^ (b - src);
if(fabs(temp) <= EPS) return src.getDis(a) < src.getDis(b);
return temp > -EPS;
}
bool cmp2(Point &a, Point &b)
{
return src.getDis(a) > src.getDis(b);
}
bool convex()
{
sort(point, point + n, cmp);
int j = n - 1;
while(j > 0 && fabs((point[j] - src) ^ (point[j - 1] - src)) < EPS)
{
--j;
}
if(j > 0) sort(point + j, point + n, cmp2);
else return false;
int now = 0, nxt;
for(int i = 1; i < n; ++i)
{
nxt = (i + 1) % n;
double temp = (point[i] - point[now]) ^ (point[nxt] - point[now]);
if(fabs(temp) < EPS)
{
//nothing to do
}
else
{
if(i - now <= 1) return false;
else now = i;
}
}
return true;
}
int main()
{
// freopen("in.txt", "r", stdin);
int T;
scanf("%d", &T);
while(T--)
{
src = Point(INF, INF);
scanf("%d", &n);
for(int i = 0; i < n; ++i)
{
point[i].input();
if(point[i].x < src.x || (fabs(point[i].x - src.x) < EPS && point[i].y < src.y))
{
src = point[i];
}
}
if(n < 6)
{
puts("NO");
continue;
}
if(convex()) puts("YES");
else puts("NO");
}
}