Description

Being the only living descendant of his grandfather, Kamran the Believer inherited all of the grandpa's belongings. The most valuable one was a piece of convex polygon shaped farm in the grandpa's birth village. The farm was originally separated from the neighboring farms by a thick rope hooked to some spikes (big nails) placed on the boundary of the polygon. But, when Kamran went to visit his farm, he noticed that the rope and some spikes are missing. Your task is to write a program to help Kamran decide whether the boundary of his farm can be exactly determined only by the remaining spikes.

Input

The first line of the input file contains a single integer t (1 <= t <= 10), the number of test cases, followed by the input data for each test case. The first line of each test case contains an integer n (1 <= n <= 1000) which is the number of remaining spikes. Next, there are n lines, one line per spike, each containing a pair of integers which are x and y coordinates of the spike.

Output

There should be one output line per test case containing YES or NO depending on whether the boundary of the farm can be uniquely determined from the input.
 
题目大意:原本有一个凸多边形,现在我们不知道它的边,它的一部分点也有可能消失了,问用剩下的点能不能确定那个多边形。
思路:先求个凸包,然后判断是否凸包相邻的两点之间都存在一个题目给出的点使得这个点在这条边上。
因为有一个点在这个边上呢,这条边就确定下来了。
嘛其实没有这么麻烦,因为我在做模板所以……
啊,对了,全部点是一条直线的时候输出NO,我上了求多边形面积的模板←_←
 
代码(0MS):
 #include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <cmath>
using namespace std; const int MAXN = ;
const double EPS = 1e-;
const double PI = acos(-1.0);//3.14159265358979323846 inline int sgn(double x) {
return (x > EPS) - (x < -EPS);
} struct Point {
double x, y;
Point() {}
Point(double x, double y): x(x), y(y) {}
void read() {
scanf("%lf%lf", &x, &y);
}
bool operator == (const Point &rhs) const {
return sgn(x - rhs.x) == && sgn(y - rhs.y) == ;
}
bool operator < (const Point &rhs) const {
if(y != rhs.y) return y < rhs.y;
return x < rhs.x;
}
Point operator + (const Point &rhs) const {
return Point(x + rhs.x, y + rhs.y);
}
Point operator - (const Point &rhs) const {
return Point(x - rhs.x, y - rhs.y);
}
Point operator * (const int &b) const {
return Point(x * b, y * b);
}
Point operator / (const int &b) const {
return Point(x / b, y / b);
}
double length() const {
return sqrt(x * x + y * y);
}
Point unit() const {
return *this / length();
}
};
typedef Point Vector; double dist(const Point &a, const Point &b) {
return (a - b).length();
} double cross(const Point &a, const Point &b) {
return a.x * b.y - a.y * b.x;
}
//ret >= 0 means turn left
double cross(const Point &sp, const Point &ed, const Point &op) {
return sgn(cross(sp - op, ed - op));
} double area(const Point& a, const Point &b, const Point &c) {
return fabs(cross(a - c, b - c)) / ;
} struct Seg {
Point st, ed;
Seg() {}
Seg(Point st, Point ed): st(st), ed(ed) {}
void read() {
st.read(); ed.read();
}
};
typedef Seg Line; bool isOnSeg(const Seg &s, const Point &p) {
return (p == s.st || p == s.ed) ||
(((p.x - s.st.x) * (p.x - s.ed.x) < ||
(p.y - s.st.y) * (p.y - s.ed.y) < ) &&
sgn(cross(s.ed, p, s.st) == ));
} bool isIntersected(const Point &s1, const Point &e1, const Point &s2, const Point &e2) {
return (max(s1.x, e1.x) >= min(s2.x, e2.x)) &&
(max(s2.x, e2.x) >= min(s1.x, e1.x)) &&
(max(s1.y, e1.y) >= min(s2.y, e2.y)) &&
(max(s2.y, e2.y) >= min(s1.y, e1.y)) &&
(cross(s2, e1, s1) * cross(e1, e2, s1) >= ) &&
(cross(s1, e2, s2) * cross(e2, e1, s2) >= );
} bool isIntersected(const Seg &a, const Seg &b) {
return isIntersected(a.st, a.ed, b.st, b.ed);
} bool isParallel(const Seg &a, const Seg &b) {
return sgn(cross(a.ed - a.st, b.ed - b.st)) == ;
} //return Ax + By + C =0 's A, B, C
void Coefficient(const Line &L, double &A, double &B, double &C) {
A = L.ed.y - L.st.y;
B = L.st.x - L.ed.x;
C = L.ed.x * L.st.y - L.st.x * L.ed.y;
} Point intersection(const Line &a, const Line &b) {
double A1, B1, C1;
double A2, B2, C2;
Coefficient(a, A1, B1, C1);
Coefficient(b, A2, B2, C2);
Point I;
I.x = - (B2 * C1 - B1 * C2) / (A1 * B2 - A2 * B1);
I.y = (A2 * C1 - A1 * C2) / (A1 * B2 - A2 * B1);
return I;
} bool isEqual(const Line &a, const Line &b) {
double A1, B1, C1;
double A2, B2, C2;
Coefficient(a, A1, B1, C1);
Coefficient(b, A2, B2, C2);
return sgn(A1 * B2 - A2 * B1) == && sgn(A1 * C2 - A2 * C1) == && sgn(B1 * C2 - B2 * C1) == ;
} struct Poly {
int n;
Point p[MAXN];//p[n] = p[0]
void init(Point *pp, int nn) {
n = nn;
for(int i = ; i < n; ++i) p[i] = pp[i];
p[n] = p[];
}
double area() {
if(n < ) return ;
double s = p[].y * (p[n - ].x - p[].x);
for(int i = ; i < n; ++i)
s += p[i].y * (p[i - ].x - p[i + ].x);
return s / ;
}
}; void Graham_scan(Point *p, int n, int *stk, int &top) {
sort(p, p + n);
top = ;
stk[] = ; stk[] = ;
for(int i = ; i < n; ++i) {
while(top && cross(p[i], p[stk[top]], p[stk[top - ]]) >= ) --top;
stk[++top] = i;
}
int len = top;
stk[++top] = n - ;
for(int i = n - ; i >= ; --i) {
while(top != len && cross(p[i], p[stk[top]], p[stk[top - ]]) >= ) --top;
stk[++top] = i;
}
} /*******************************************************************************************/ Point p[MAXN];
Poly poly;
int stk[MAXN], top;
int n, T; bool check() {
poly.n = top;
for(int i = ; i < top; ++i) poly.p[i] = p[stk[i]];
poly.p[poly.n] = poly.p[];
if(sgn(poly.area()) == ) return false;
for(int i = ; i < poly.n; ++i) {
bool flag = false;
for(int j = ; j < n; ++j) {
if(p[j] == poly.p[i] || p[j] == poly.p[i + ]) continue;
if(isOnSeg(Seg(poly.p[i], poly.p[i + ]), p[j])) {
flag = true;
break;
}
}
if(!flag) return false;
}
return true;
} int main() {
scanf("%d", &T);
while(T--) {
scanf("%d", &n);
for(int i = ; i < n; ++i) p[i].read();
Graham_scan(p, n, stk, top);
if(check()) puts("YES");
else puts("NO");
}
}

POJ 1228 Grandpa's Estate(凸包唯一性判断)的更多相关文章

  1. POJ 1228 Grandpa's Estate 凸包 唯一性

    LINK 题意:给出一个点集,问能否够构成一个稳定凸包,即加入新点后仍然不变. 思路:对凸包的唯一性判断,对任意边判断是否存在三点及三点以上共线,如果有边不满足条件则NO,注意使用水平序,这样一来共线 ...

  2. POJ 1228 Grandpa's Estate(凸包)

    Grandpa's Estate Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 11289   Accepted: 3117 ...

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

    稳定凸包问题 要求每条边上至少有三个点,且对凸包上点数为1,2时要特判 巨坑无比,调了很长时间= = //POJ 1228 //稳定凸包问题,等价于每条边上至少有三个点,但对m = 1(点)和m = ...

  4. POJ 1228 Grandpa's Estate --深入理解凸包

    题意: 判断凸包是否稳定. 解法: 稳定凸包每条边上至少有三个点. 这题就在于求凸包的细节了,求凸包有两种算法: 1.基于水平序的Andrew算法 2.基于极角序的Graham算法 两种算法都有一个类 ...

  5. 简单几何(求凸包点数) POJ 1228 Grandpa's Estate

    题目传送门 题意:判断一些点的凸包能否唯一确定 分析:如果凸包边上没有其他点,那么边想象成橡皮筋,可以往外拖动,这不是唯一确定的.还有求凸包的点数<=2的情况一定不能确定. /********* ...

  6. poj - 1228 - Grandpa's Estate

    题意:原来一个凸多边形删去一些点后剩n个点,问这个n个点能否确定原来的凸包(1 <= 测试组数t <= 10,1 <= n <= 1000). 题目链接:http://poj. ...

  7. 【POJ】1228 Grandpa's Estate(凸包)

    http://poj.org/problem?id=1228 随便看看就能发现,凸包上的每条边必须满足,有相邻的边和它斜率相同(即共线或凸包上每个点必须一定在三点共线上) 然后愉快敲完凸包+斜率判定, ...

  8. 【POJ 1228】Grandpa's Estate 凸包

    找到凸包后暴力枚举边进行$check$,注意凸包是一条线(或者说两条线)的情况要输出$NO$ #include<cmath> #include<cstdio> #include ...

  9. 凸包稳定性判断:每条边上是否至少有三点 POJ 1228

    //凸包稳定性判断:每条边上是否至少有三点 // POJ 1228 #include <iostream> #include <cstdio> #include <cst ...

随机推荐

  1. 微信小程序之数据传递

    本文主要介绍,页面跳转间的数据传递.传递的数据类型主要有1,基本数据类型:2,对象:3,数组集合: 先告诉你,本质上都是string类型传递.但是对于对象和数组集合的传递需要小小的处理一下传递时的数据 ...

  2. 集合栈计算机(The SetStack Computer, ACM/ICPC NWERC 2006,Uva12096)

    集合栈计算机(The SetStack Computer, ACM/ICPC NWERC 2006,Uva12096) 题目描述 有一个专门为了集合运算而设计的"集合栈"计算机.该 ...

  3. 【模板】缩点(tarjan,DAG上DP)

    题目背景 缩点+DP 题目描述 给定一个n个点m条边有向图,每个点有一个权值,求一条路径,使路径经过的点权值之和最大.你只需要求出这个权值和. 允许多次经过一条边或者一个点,但是,重复经过的点,权值只 ...

  4. react-router-dom和本地服务本地开发 (node、webpack)

    场景 使用react 做开发,避免会使用react-router React Router 已经是V4的版本 React Router 目前已经被划分成了三个包:react-router,react- ...

  5. 配置一个nginx+php-fpm的web服务器

    一.基本信息 系统(L):CentOS 6.9 #下载地址:http://mirrors.sohu.com 反代&负载均衡(N):NGINX 1.14.0 #下载地址:http://nginx ...

  6. hadoop生态搭建(3节点)-11.storm配置

    # http://archive.apache.org/dist/storm/apache-storm-1.1.0/ # ======================================= ...

  7. python之内存与编码的那点事

    一.初始编码 ASCII 码不支持中文 是py2版本中的默认编码 ​Unicode 万国码, 英文使用16位(即两个字节​),中文使用32位(四个字节) ​utf-8 美国最少使用八位(1字节), 欧 ...

  8. UDP server Code

    Code Example: The following programs demonstrate the use of getaddrinfo(), gai_strerror(), freeaddri ...

  9. C语言#ifdef等宏的妙用

    这几个宏是为了进行条件编译.一般情况下,源程序中所有的行都参加编译.但是有时希望对其中一部分内容只在满足一定条件才进行编译,也就是对一部分内容指定编译的条件,这就是“条件编译”.有时,希望当满足某条件 ...

  10. EEPROM读写学习笔记与I2C总线(二)

    无论任何电子产品都会涉及到数据的产生与数据的保存,这个数据可能并不是用来长久保存,只是在运行程序才会用到,有些数据体量较大对于获取时效性并不太强,各种各样的数据也就有不同的存储载体,这次在EEPROM ...