HDOJ 5533 Dancing Stars on Me(凸包,convex hall)

来源:互联网 发布:淘宝正义哥之家店铺 编辑:程序博客网 时间:2024/06/06 06:54

  • 题目描述
  • AC代码

原题链接

题目描述

给定n个点,判断这n个点组成的凸多边形是否是正多边形。典型的凸包问题,我们可以把n个点按逆时针方向排列起来,然后算各个定点组成的边的大小,当所有边的大小相等时,则为正多边形。
不过这里需要注意在已有的正多边形的边上再增加点时,则不满足要求。
如题目给出的样例,
Sample Input
3
3
0 0
1 1
1 0
4
0 0
0 1
1 0
1 1
5
0 0
0 1
0 2
2 2
2 0

Sample Output
NO
YES
NO
其中,第三个样例中,输入的 0 0, 0 2, 2 2,2 0已经构成了一个正方形,这是点(0, 1)在边(0 ,0)(0, 2)上,则不满足要求。
最后,具体求解时采用graham算法。

AC代码

#include <iostream>#include <algorithm>#include <vector>#include <cmath>using namespace std;const int MAXN = 1005;const double PI = acos(-1.0);const double EPS = 1E-6;int T, N, L;struct Point{    int x;    int y;} p[MAXN];vector<Point> vec;double dist(Point a, Point b) {    return sqrt((a.x - b.x)*(a.x - b.x) + (a.y - b.y)*(a.y - b.y));}double crossProduct(Point a, Point b, Point c) { // ab * ac    return (b.x - a.x)*(c.y - a.y) - (b.y - a.y)*(c.x - a.x) - 0.0;}bool cmp(Point a, Point b) {    double cp = crossProduct(p[0], a, b);    if (cp > EPS) return true;    else if (cp < -EPS) return false;    else return dist(p[0], a) < dist(p[0], b);}int findLf(Point p[]) {     // find lowest leftest point/vertice.    int index = 0;    for (int i = 1; i < N; i++) {        if (p[i].y < p[index].y) index = i;        else if (p[i].y == p[index].y && p[i].x < p[index].x) index = i;    }    return index;}void graham(Point p[]) {    // graham algorithm for convex hall.    vec.clear();    vec.push_back(p[0]); vec.push_back(p[1]);    int top = 1;    for (int i = 2; i <= N; i++) {           while (top >= 1 && crossProduct(vec[top - 1], vec[top], p[i]) <= 0) {            vec.pop_back();            top--;        }        vec.push_back(p[i]);        top++;    }}int main() {    cin >> T;    while (T--) {        cin >> N;        for (int i = 0; i < N; ++i) {            cin >> p[i].x >> p[i].y;        }        int lf = findLf(p);        swap(p[0], p[lf]);        p[N] = p[0];        sort(p + 1, p + N, cmp);        graham(p);        bool flag = true;        if ((int)vec.size() < N+1) {            cout << "NO" << endl;            continue;        }        double ans = dist(vec[0], vec[1]);        for (int i = 2; i < (int)vec.size(); i++) {            if (ans != dist(vec[i - 1], vec[i])) {                flag = false;                break;            }        }        flag ? cout << "YES" : cout << "NO";        cout << endl;    }    return 0;}