• 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
  • 相关阅读:
    安装oracle常见问题和解决方案
    配置VNC
    爬虫
    启动Tomcat报异常host-manager does not exist or is not a readable directory
    linux升级openssl
    linux6的yum源
    linux升级openssh
    linux操作oracle
    Linux 系统结构
    Linux MD5值递归比对目录中的文件是否有修改
  • 原文地址:https://www.cnblogs.com/hzf-sbit/p/3940190.html
Copyright © 2020-2023  润新知