zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    感悟
    shadow classification
    interpolation
    c语言调试技巧
    注册博客园
    用jQuery实现图片预加载和等比例缩小,大图可以点击关闭
    焦点图,带数字显示,支持常见浏览器
    又一个jquery轮播效果,焦点图,带数字显示序号,这个可以添加对应标题在图片上,支持主流浏览器
    纯css下拉菜单,支持CSS3圆角
    Jquery 下拉菜单,可以设置颜色,支持CSS3圆角
  • 原文地址:https://www.cnblogs.com/hzf-sbit/p/3940190.html
Copyright © 2011-2022 走看看