题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=5533
题意:给n个点,问是否能构成正n多边形。
求个凸包然后判断一下就可以了。其实只需要判断边长相等就可以了,边长相等的话角一定相等....高中学的都忘干净了....
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <queue>
#include <cmath>
using namespace std;
const double eps = 1e-8;
const double PI = acos(-1.0);
int sgn(double x) {
if(fabs(x) < eps)return 0;
if(x < 0)return -1;
else return 1;
}
struct Point {
double x,y;
Point(){}
Point(double _x,double _y) {
x = _x;y = _y;
}
Point operator -(const Point &b)const {
return Point(x - b.x,y - b.y);
}
double operator ^(const Point &b)const {
return x*b.y - y*b.x;
}
double operator *(const Point &b)const {
return x*b.x + y*b.y;
}
void transXY(double B) {
double tx = x,ty = y;
x = tx*cos(B) - ty*sin(B);
y = tx*sin(B) + ty*cos(B);
}
};
struct Line {
Point s,e;
Line(){}
Line(Point _s,Point _e) {
s = _s;e = _e;
}
pair<int,Point> operator &(const Line &b)const {
Point res = s;
if(sgn((s-e)^(b.s-b.e)) == 0) {
if(sgn((s-b.e)^(b.s-b.e)) == 0) return make_pair(0,res);
else return make_pair(1,res);
}
double t = ((s-b.s)^(b.s-b.e))/((s-e)^(b.s-b.e));
res.x += (e.x-s.x)*t;
res.y += (e.y-s.y)*t;
return make_pair(2,res);
}
};
double dist(Point a,Point b) {
return sqrt((a-b)*(a-b));
}
const int MAXN = 101;
Point list[MAXN];
Point Stack[MAXN];
int top;
bool _cmp(Point p1,Point p2) {
if(p1.x != p2.x) return p1.x < p2.x;
else return p1.y < p2.y;
}
int Andrew(Point *p, int n, Point *ch) {
sort(p, p + n, _cmp);
int m = 0;
for(int i = 0; i < n; i++) {
while(m > 1 && ((ch[m - 1] - ch[m - 2]) ^ (p[i] - ch[m - 2])) <= 0) m--;
ch[m++] = p[i];
}
int k = m;
for(int i = n - 2; i >= 0; i--) {
while(m > k && ((ch[m - 1] - ch[m - 2]) ^ (p[i] - ch[m - 2])) <= 0) m--;
ch[m++] = p[i];
}
if(n > 1) m--;
return m;
}
int main() {
int t;
scanf("%d", &t);
while(t--) {
int n;
scanf("%d", &n);
for(int i = 0; i < n; i++) {
scanf("%lf %lf", &list[i].x, &list[i].y);
}
top = Andrew(list, n, Stack);
if(top != n) puts("NO");
else {
int flag = 1;
for(int i = 0; i < top - 1; i++) { //判断边长相等
if(dist(Stack[i], Stack[(i + 1)%top]) != dist(Stack[(i + 1)%top], Stack[(i + 2)%top])) {
flag = 0;
break;
}
}
if(!flag) {
puts("NO");
continue;
}
double angle = ((Stack[1] - Stack[0]) ^ (Stack[2] - Stack[1])); //判断角度相等
for(int i = 0; i < top; i++) {
if(((Stack[(i + 1)%top] - Stack[i]) ^ (Stack[(i + 2)%top] - Stack[(i + 1)%top])) != angle) {
flag = 0;
break;
}
}
if(!flag) puts("NO");
else puts("YES");
}
}
return 0;
}