hdoj 3685 Rotational Painting

来源:互联网 发布:网络歌曲很少歌曲 编辑:程序博客网 时间:2024/06/04 01:22

求出凸包和重心,然后一个个看凸包上的相邻点放在地面上能否放稳即可。

比赛中写的代码很搓。。。

/* * Author: stormdpzh * Created Time: 2012/8/17 15:10:30 * File Name: f.cpp */#include <iostream>#include <cstdio>#include <sstream>#include <cstring>#include <string>#include <cmath>#include <vector>#include <queue>#include <stack>#include <map>#include <set>#include <algorithm>#include <functional>#define sz(v) ((int)(v).size())#define rep(i, n) for(int i = 0; i < n; i++)#define repf(i, a, b) for(int i = a; i <= b; i++)#define repd(i, a, b) for(int i = a; i >= b; i--)#define out(n) printf("%d\n", n)#define mset(a, b) memset(a, b, sizeof(a))#define wh(n) while(1 == scanf("%d", &n))#define whz(n) while(1 == scanf("%d", &n) && n != 0)#define lint long longusing namespace std;const int INF = 1 << 30;const int MaxN = 50005;const double eps = 1e-12;int sgn(double d){    if(d > eps) return 1;    if(d < -eps) return -1;    return 0;}struct Point {    double x, y;    Point() : x(0.0), y(0.0) {}    Point(double _x, double _y) : x(_x), y(_y) {}    void read() {        scanf("%lf%lf", &x, &y);    }};Point pnt[MaxN], res[MaxN];int n;Point core;struct Node {    double x, dis;    Node() {}    Node(double _x, double _dis) : x(_x), dis(_dis) {}    bool operator < (const Node &t) const {        if(sgn(x - t.x) != 0) return sgn(x - t.x) < 0;        else return sgn(dis - t.dis) < 0;    }};set<Node> st;set<Node>::iterator it;int total;bool mult(Point sp, Point ep, Point op){    return sgn((sp.x - op.x) * (ep.y - op.y) - (ep.x - op.x) * (sp.y - op.y)) >= 0;}bool operator < (const Point &l, const Point &r){    return sgn(l.y - r.y) < 0 || (sgn(l.y - r.y) == 0 && sgn(l.x - r.x) < 0);}Point operator - (const Point &l, const Point &r){    return Point(l.x - r.x, l.y - r.y);}double operator * (const Point &l, const Point &r){    return (l.x * r.x + l.y * r.y);}double operator ^ (const Point &l, const Point &r){    return (l.x * r.y - l.y * r.x);}int get_convex(){    int i, len, k = 0, top = 1;    sort(pnt, pnt + n);    if (n == 0) return 0;    res[0] = pnt[0];    if (n == 1) return 1;    res[1] = pnt[1];    if (n == 2) return 2;    res[2] = pnt[2];    for (i = 2; i < n; i++) {        while (top && mult(pnt[i], res[top], res[top - 1])) top--;        res[++top] = pnt[i];    }    len = top;    res[++top] = pnt[n - 2];    for(int i = n - 3; i >= 0; i--) {        while(top != len && mult(pnt[i], res[top], res[top - 1])) top--;        res[++top] = pnt[i];    }    return top;}Point get_point(){    Point p, s;    double tp, area = 0.0, tpx = 0.0, tpy = 0.0;    p.x = pnt[0].x; p.y = pnt[0].y;    for(int i = 1; i <= n; i++) {        s.x = pnt[(i == n) ? 0 : i].x;        s.y = pnt[(i == n) ? 0 : i].y;        tp = fabs((p.x * s.y - s.x * p.y));         area += tp / 2.0;        tpx += (p.x + s.x) * tp;         tpy += (p.y + s.y) * tp;        p.x = s.x;         p.y = s.y;    }    s.x = tpx / (6.0 * area);     s.y = tpy / (6.0 * area);    return s;}bool judge(int x, int y){    Point A = core - res[x];    Point B = core - res[y];    Point C = res[x] - res[y];    if(sgn(A * (Point(0.0, 0.0) - C) <= 0)) return false;    if(sgn(B * C) <= 0) return false;    return true;}double get_dis(int x, int y){    Point A = Point(0, 0) - res[x];    Point C = res[y] - res[x];    double area = fabs(A ^ C) / 2.0;    return (area / sqrt((res[x].x - res[y].x) * (res[x].x - res[y].x) + (res[x].y - res[y].y) * (res[x].y - res[y].y)));}bool is_low(int x, int y){    Point A = res[x], B = res[y];    if(sgn(A.x - B.x) == 0) return sgn(A.x) < 0;    if(sgn(A.y - B.y) == 0) return sgn(B.y) < 0;    double tmp = (-A.x) * (A.y - B.y) / (A.x - B.x) + A.y;    return sgn(tmp) < 0;}int gao(){    int cnt = 0;    bool f = false;    bool d = 0.0;    st.clear();    for(int i = 0; i < total; i++) {        int j = (i + 1) % total;        double x;        double dis = get_dis(i, j);        if(is_low(i,j)) dis = -dis;        if(res[i].x - res[j].x == 0.0) {            if(!f || d != dis) {                if(judge(i, j)) {                    cnt++;                      f = true;                    d = dis;                      }            }        }        else {            x = (res[i].y - res[j].y) / (res[i].x - res[j].x);            if(st.find(Node(x, dis)) == st.end()) {                if(judge(i, j)) {                    cnt++;                            st.insert(Node(x, dis));                }            }        }    }    return cnt;}int main(){    int t;    scanf("%d", &t);    while(t--) {        scanf("%d", &n);        for(int i = 0; i < n; i++) pnt[i].read();        core = get_point();        total = get_convex();        out(gao());    }    return 0;}

原创粉丝点击