209. Areas
time limit per test: 0.25 sec.
memory limit per test: 65536 KB
memory limit per test: 65536 KB
input: standard
output: 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.
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
5
0 0 1 0
1 0 1 1
1 1 0 1
0 1 0 0
0 0 1 1
0 0 1 0
1 0 1 1
1 1 0 1
0 1 0 0
0 0 1 1
Output
2
0.5000
0.5000
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; }