• SGU 209. Areas


    209. Areas

    time limit per test: 0.25 sec.
    memory limit per test: 65536 KB
    input: standard
    output: standard




    Consider N different lines on the plane. They divide it to several parts,some of which are finite, some infinite. 

    Your task in this problem is for each finite part to find its area. 

    Input

    The first line of the input file contains N — the number of lines (1 ≤ N ≤ 80). Each of next N lines contains four integer numbers x1, y1, x2 and y2 — the coordinates of two different points of the line. 

    All coordinates do not exceed 102 by their absolute value. 

    No two lines coincide. 

    Output

    First output K — the number of finite parts among those the lines divide the plane to. 

    Next K lines of the output file must contain area parts sorted in non-decreasing order. You answer must be accurate up to 10-4

    Due to floating point precision losses possible, do not consider parts with area not exceeding 10-8

    Sample test(s)

    Input
     
     

    0 0 1 0 
    1 0 1 1 
    1 1 0 1 
    0 1 0 0 
    0 0 1 1 
     
     

    Output
     
     

    0.5000 
    0.5000 
     
     

    题意

    求平面上一堆直线围成的所有封闭多边形面积。


    ID: Date'n'Time: Name: Task: .Ext: Status: Time: Memory:
    1587815 27.08.14 15:40 HuZhifeng 209 .CPP Accepted 15 ms 458 kb
    1587814 27.08.14 15:00 HuZhifeng 209 .CPP Wrong answer on test 12 15 ms 554 kb
    1587813 27.08.14 14:55 HuZhifeng 209 .CPP Memory Limit Exceeded on test 12 218 ms 99406 kb
    1587812 27.08.14 14:53 HuZhifeng 209 .CPP Runtime Error on test 12 15 ms 378 kb
     
    又RE又ME又WA。。太爽啦!
     
    坑爹题啊!
    copy叉姐的。。。不忍直视。
     
    #include <bits/stdc++.h>
    #define rep(_i, _j) for(int _i = 1; _i <= _j; ++_i)
    const int inf = 0x3f3f3f3f;
    typedef long long LL;
    typedef double DB;
    using namespace std;
    /*{ 基本定义,二维点,向量,叉积,点积,基本运算。*/
    
    const DB eps = 1e-8;
    #define sqr(x) ((x) * (x))
    int dcmp(DB x) {
        return x < -eps ? -1 : eps < x;
    }
    bool chk_equality(DB x, DB y) {
        return dcmp(x - y) == 0;
    }
    
    struct Point {
        DB x, y;
        Point() {}
        Point(DB x, DB y): x(x), y(y) {}
        DB arg() {
            return atan2(y, x);
        }
        DB norm() {
            return sqrt(sqr(x) + sqr(y));
        }
        Point normalize() {
            DB d = norm();
            return Point(x / d, y / d);
        }
        void read() {
            scanf("%lf%lf", &x, &y);
        }
    };
    typedef Point Vector;
    bool operator == (const Point a, const Point b) {
        return dcmp(a.x - b.x) == 0 && dcmp(a.y - b.y) == 0;
    }
    bool operator < (const Point a, const Point b) {
        return dcmp(a.x - b.x) < 0 || (dcmp(a.x - b.x) == 0 && dcmp(a.y - b.y) < 0);
    }
    Vector operator + (Point a, Point b) {
        return Vector(a.x + b.x, a.y + b.y);
    }
    Vector operator - (Point a, Point b) {
        return Vector(a.x - b.x, a.y - b.y);
    }
    Vector operator * (Vector v, DB p) {
        return Vector(v.x * p, v.y * p);
    }
    Vector operator / (Vector v, DB p) {
        return Vector(v.x / p, v.y / p);
    }
    DB dot(Vector a, Vector b) {
        return a.x * b.x + a.y * b.y;
    }
    DB cross(Vector a, Vector b) {
        return a.x * b.y - a.y * b.x;
    }
    DB length(Vector a) {
        return sqrt(dot(a, a));
    }
    
    /*} end*/
    
    struct Line {
        Point p;
        Vector d;
        Line() {}
        Line(Point p, Vector d): p(p), d(d) {}
    };
    bool operator == (Line a, Line b) {
        return a.p == b.p && dcmp(cross(a.d, b.d)) == 0;
    }
    /*{ 常用函数*/
    
    Point get_intersection(Line a, Line b) {
        DB s1 = cross(a.p - b.p, b.d);
        DB s2 = cross(a.p + a.d - b.p, b.d);
        return (a.p * s2 - (a.p + a.d) * s1) / (s2 - s1);
    }
    
    /*} end*/
    
    const int maxn = 80 + 2;
    
    int n;
    Line lines[maxn];
    Point tmp1, tmp2;
    vector<Point> points;
    int get_point_id(Point a) {
        return lower_bound(points.begin(), points.end(), a) - points.begin();
    }
    const int maxv = maxn;
    const int maxe = maxv * maxv * 2;
    struct Edge {
        int edge;
        int head[maxe], to[maxe], next[maxe];
        Edge() {
            edge = 0;
            memset(head, -1, sizeof head);
        }
        void addedge(int u, int v) {
            to[edge] = v;
            next[edge] = head[u];
            head[u] = edge++;
        }
    } E;
    int next[maxe];
    bool vis[maxe];
    
    int main() {
    #ifndef ONLINE_JUDGE
        freopen("209.in", "r", stdin); freopen("209.out", "w", stdout);
    #endif
        cin >> n;
        for(int i = 0; i < n; ++i) {
            tmp1.read(), tmp2.read();
            lines[i] = Line(tmp1, tmp2 - tmp1);
        }
        for(int i = 0; i < n; ++i) {
            for(int j = 0; j < i; ++j) {
                if(!chk_equality(cross(lines[i].d, lines[j].d), 0)) {
                    points.push_back(Point(get_intersection(lines[i], lines[j])));
                }
            }
        }
        sort(points.begin(), points.end());
        points.erase(unique(points.begin(), points.end()), points.end());
        for(int i = 0; i < n; ++i) {
            vector<DB> lambdas;
            Vector d = lines[i].d.normalize();
            for(int j = 0; j < n; ++j) {
                if(!chk_equality(cross(d, lines[j].d), 0)) {
                    lambdas.push_back(dot(get_intersection(lines[i], lines[j]) - lines[i].p, d));
                }
            }
            sort(lambdas.begin(), lambdas.end());
            lambdas.erase(unique(lambdas.begin(), lambdas.end(), chk_equality), lambdas.end());
            for(int j = 1, sz = lambdas.size(); j < sz; ++j) {
                int a = get_point_id(lines[i].p + d * lambdas[j]);
                int b = get_point_id(lines[i].p + d * lambdas[j - 1]);
                E.addedge(b, a);
                E.addedge(a, b);
            }
        }
        memset(next, -1, sizeof next);
        for(int i = 0, sz = points.size(); i < sz; ++i) {
            vector<pair<DB, int> > adjacent;
            for(int j = E.head[i]; j != -1; j = E.next[j]) {
                adjacent.push_back(make_pair((points[E.to[j]] - points[i]).arg(), j));
            }
            sort(adjacent.begin(), adjacent.end());
            for(int j = 0, sz = adjacent.size(); j < sz; ++j) {
                next[adjacent[(j + 1) % sz].second ^ 1] = adjacent[j].second;
            }
        }
        memset(vis, false, sizeof vis);
        vector<DB> areas;
        for(int i = 0; i < E.edge; ++i) {
            if(!vis[i]) {
                vector<int> boundary;
                int j = i;
                do {
                    if(!boundary.empty() && (boundary.back() ^ j) == 1) {
                        boundary.pop_back();
                    } else {
                        boundary.push_back(j);
                    }
                    vis[j] = true;
                    j = next[j];
                } while(!vis[j]);
                if(i == j) {
                    DB area = 0.0;
                    for(int k = 0, sz = boundary.size(); k < sz; ++k) {
                        area += cross(points[E.to[boundary[k] ^ 1]], points[E.to[boundary[k]]]);
                    }
                    area /= 2.0;
                    if(dcmp(area) > 0) {
                        areas.push_back(area);
                    }
                }
            }
        }
        sort(areas.begin(), areas.end());
        printf("%d
    ", (int)areas.size());
        for(int i = 0, sz = areas.size(); i < sz; ++i) {
            printf("%.4lf
    ", areas[i]);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    leetcode——33.搜索旋转排序数组
    leetcode——80.删除排序数组中的重复项2
    leetcode——26.删除排序数组中的重复项
    leetcode——18.四数之和
    leetcode——42.接雨水
    leetcode——11.盛最多水的容器
    leetcode——16.最接近的三数之和
    leetcode——15.三数之和
    leetcode——1002.查找常用字符
    004 linux学习:【第4篇】之nginx
  • 原文地址:https://www.cnblogs.com/hzf-sbit/p/3940190.html
Copyright © 2020-2023  润新知