Lightoj 1203 (计算几何 凸包)

来源:互联网 发布:软件人才外派 编辑:程序博客网 时间:2024/05/01 05:45

题目链接:点击这里

题意:平面上有n个点, 求某一个点使得从这个点出发看遍所有的点的旋转角最小.

求一次凸包之后答案就是凸包上的最小角, 扫一遍就好了. 计算角度的时候精度要求很高, 正好验一发板子.

#include <bits/stdc++.h>using namespace std;const double eps = 1e-8;const double INF = 1e20;const double pi = acos (-1.0);int dcmp (double x) {    if (fabs (x) < eps) return 0;    return (x < 0 ? -1 : 1);}inline double sqr (double x) {return x*x;}//*************点struct Point {    double x, y;    Point (double _x = 0, double _y = 0):x(_x), y(_y) {}    void input () {scanf ("%lf%lf", &x, &y);}    void output () {printf ("%.2f %.2f", x, y);}    bool operator == (const Point &b) const {        return (dcmp (x-b.x) == 0 && dcmp (y-b.y) == 0);    }    bool operator < (const Point &b) const {        return (dcmp (x-b.x) == 0 ? dcmp (y-b.y) < 0 : x < b.x);    }    Point operator + (const Point &b) const {        return Point (x+b.x, y+b.y);    }    Point operator - (const Point &b) const {        return Point (x-b.x, y-b.y);    }    Point operator * (double a) {        return Point (x*a, y*a);    }    Point operator / (double a) {        return Point (x/a, y/a);    }    double len2 () {//返回长度的平方        return sqr (x) + sqr (y);    }    double len () {//返回长度        return sqrt (len2 ());    }};double cross (Point a, Point b) {//叉积    return a.x*b.y-a.y*b.x;}double dot (Point a, Point b) {//点积    return a.x*b.x + a.y*b.y;}double distance (Point a, Point b) {//两个点的距离    Point p = b-a; return p.len ();}double rad_degree (double rad) {//弧度转化为角度    return rad/pi*180;}double rad (Point a, Point b) {//两个向量的夹角    return fabs (atan2 (fabs (cross (a, b)), dot (a, b)) );}int ConvexHull (Point *p, Point *ch, int n) {//求凸包    //所有的点集 凸包点集 点集的点数    sort (p, p+n);    int m = 0;    for (int i = 0; i < n; i++) {        while (m > 1 && cross (ch[m-1]-ch[m-2], p[i]-ch[m-1]) <= 0)            m--;        ch[m++] = p[i];    }    int k = m;    for (int i = n-2; i >= 0; i--) {        while (m > k && cross (ch[m-1]-ch[m-2], p[i]-ch[m-1]) <= 0)            m--;        ch[m++] = p[i];    }    if (n > 1)        m--;    return m;}#define maxn 111111Point p[maxn], ch[maxn];int n, m;int main () {    int t, kase = 0;    cin >> t;    while (t--) {        printf ("Case %d: ", ++kase);        cin >> n;        for (int i = 0; i < n; i++) p[i].input ();        m = ConvexHull (p, ch, n);        if (m == 1) {            printf ("0\n");            continue;        }        double ans = INF;        for (int i = 0; i < m; i++) {            ans = min (ans, rad (ch[(i+1)%m]-ch[i], ch[(i-1+m)%m]-ch[i]));        }        printf ("%.10f\n", rad_degree(ans));    }    return 0;}
0 0
原创粉丝点击