Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <cstdio>
- #include <set>
- #include <cmath>
- #include <vector>
- #include <algorithm>
- #include <numeric>
- #include <ctime>
- #define _GLIBCXX_DEBUG
- #define _CRT_SECURE_NO_WARNINGS
- using namespace std;
- typedef long long ll;
- typedef long double ld;
- bool solve();
- ll time()
- {
- return (ll)clock() * 1000LL / CLOCKS_PER_SEC;
- }
- int main()
- {
- //#ifdef ONLINE_JUDGE
- // freopen("mirror.in", "r", stdin); freopen("mirror.out", "w", stdout);
- //#elif
- //freopen("in.txt", "r", stdin);
- //#endif
- int t = 1;
- #ifdef ONLINE_JUDGE
- t = 1;
- #endif
- while (t--)
- solve();
- #ifndef ONLINE_JUDGE
- // cerr << "time: " << time() << " ms" << endl;
- #endif
- return 0;
- }
- const ld eps1 = 1e-9;
- const ld eps2 = 1e-8;
- struct Point
- {
- ld x, y;
- Point():
- x(0),
- y(0) {};
- Point(ld x, ld y):
- x(x),
- y(y) {};
- ld operator^(Point p)
- {
- return x * p.y - y * p.x;
- }
- ld operator*(Point p)
- {
- return x * p.x + y * p.y;
- }
- Point operator*(ld k)
- {
- return Point(x * k, y * k);
- }
- void operator*=(ld k)
- {
- x *= k;
- y *= k;
- }
- bool operator==(Point p)
- {
- return abs(p.x - x) < eps1 && abs(p.y - y) < eps1;
- }
- Point operator+(Point p)
- {
- return Point(x + p.x, y + p.y);
- }
- void operator+=(Point p)
- {
- x += p.x;
- y += p.y;
- }
- Point operator-(Point p)
- {
- return Point(x - p.x, y - p.y);
- }
- void operator-=(Point p)
- {
- x -= p.x;
- y -= p.y;
- }
- void read()
- {
- ll X, Y;
- cin >> X >> Y;
- x = X;
- y = Y;
- }
- void print()
- {
- cout << x << " " << y << "\n";
- }
- };
- struct Line
- {
- ld a, b, c;
- Line():
- a(1),
- b(0),
- c(0) {}
- Line(ld a, ld b, ld c):
- a(a),
- b(b),
- c(c) {}
- Line(Point p, Point q):
- a(p.y - q.y),
- b(q.x - p.x),
- c(p.x * (q.y - p.y) + p.y * (p.x - q.x)) {}
- ld operator()(Point p)
- {
- return a * p.x + b * p.y + c;
- }
- Point norm()
- {
- return Point(a, b);
- }
- Point dir()
- {
- return Point(-b, a);
- }
- void read()
- {
- ll A, B, C;
- cin >> A >> B >> C;
- c = C;
- b = B;
- a = A;
- }
- void print()
- {
- cout << a << " " << b << " " << c << "\n";
- }
- Line perp(Point p)
- {
- return Line(-b, a, p.x * b - a * p.y);
- }
- };
- const int N = 100000;
- Line l[N];
- vector<Point> q;
- set<int> kek[N];
- vector<int> mem[N], used[N];
- vector<pair<int, int> > g[N];
- bool parallel(Line l, Line k)
- {
- return abs(l.a * k.b - k.a * l.b) < eps1;
- }
- Point intersect(Line l1, Line l2)
- {
- Point p;
- p.y = -(l1.a * l2.c - l2.a * l1.c) / (l1.a * l2.b - l2.a * l1.b);
- p.x = -(l1.b * l2.c - l2.b * l1.c) / (l1.b * l2.a - l2.b * l1.a);
- return p;
- }
- bool cmp1(int a, int b)
- {
- if (abs(q[a].x - q[b].x) > eps1)
- return q[a].x < q[b].x;
- return q[a].y < q[b].y;
- }
- ld dist(Point p, Point q)
- {
- return sqrt((p.x - q.x) * (p.x - q.x) + (p.y - q.y) * (p.y - q.y));
- }
- vector<ld> ans;
- bool f(Point p)
- {
- return p.y > eps1 || (abs(p.y) < eps1 && p.x > eps1);
- }
- Point curpoint;
- bool cmp2(pair<int, int> a, pair<int, int> b)
- {
- Point v = q[a.first] - curpoint;
- Point u = q[b.first] - curpoint;
- bool x = f(v), y = f(u);
- if (x != y)
- return x;
- return ((v ^ u) > 0);
- }
- vector<Point> cur;
- ld sq()
- {
- int n = cur.size();
- ld sum = 0;
- for (int i = 1; i <= n; i++)
- {
- sum += (cur[i % n].x - cur[i - 1].x) * (cur[i % n].y + cur[i - 1].y) / (ld)2;
- if (i == n)
- return sum + (cur[0].x - cur[i % n].x) * (cur[0].y + cur[i % n].y) / (ld)2;
- }
- return 0;
- }
- bool solve()
- {
- ios::sync_with_stdio(0);
- cout.precision(100);
- cerr.precision(5);
- int n;
- cin >> n;
- for (int i = 0; i < n; i++)
- {
- Point P, Q;
- P.read();
- Q.read();
- l[i] = Line(P, Q);
- }
- for (int i = 0; i < n; i++)
- for (int j = i + 1; j < n; j++)
- if (!parallel(l[i], l[j]))
- {
- Point P = intersect(l[i], l[j]);
- bool ok = false;
- for (int k = 0; k < q.size(); k++)
- if (abs(P.x - q[k].x) < eps1 && abs(P.y - q[k].y) < eps1)
- {
- ok = true;
- kek[i].insert(k);
- kek[j].insert(k);
- break;
- }
- if (!ok)
- {
- kek[i].insert(q.size());
- kek[j].insert(q.size());
- q.push_back(P);
- }
- }
- for (int i = 0; i < n; i++)
- {
- for (auto it : kek[i])
- mem[i].push_back(it);
- sort(mem[i].begin(), mem[i].end(), cmp1);
- for (int j = 1; j < mem[i].size(); j++)
- {
- int v = mem[i][j], u = mem[i][j - 1];
- // rev[v].push_back(g[u].size());
- //rev[u].push_back(g[v].size());
- g[v].push_back({u, g[u].size()});
- g[u].push_back({v, g[v].size() - 1});
- used[v].push_back(0);
- used[u].push_back(0);
- }
- }
- n = q.size();
- for (int i = 0; i < n; i++)
- {
- curpoint = q[i];
- sort(g[i].begin(), g[i].end(), cmp2);
- }
- for (int i = 0; i < n; i++)
- for (int j = 0; j < g[i].size(); j++)
- {
- int k = 0;
- while (g[g[i][j].first][k].first != i)
- k++;
- g[i][j].second = k;
- }
- for (int i = 0; i < n; i++)
- for (int j = 0; j < g[i].size(); j++)
- if (!used[i][j])
- {
- cur.clear();
- int v = i, cnt = j;
- while (!used[v][cnt])
- {
- cur.push_back(q[v]);
- used[v][cnt] = 1;
- int nextv = g[v][cnt].first;
- int nextcnt = g[v][cnt].second;
- v = nextv;
- cnt = nextcnt;
- cnt = (cnt + (int)g[v].size() - 1) % (int)g[v].size();
- }
- // for (int i = 0; i < cur.size(); i++)
- // cerr << cur[i].x << " " << cur[i].y << endl;
- // cout << endl;
- ld d = -sq();
- if (d > eps2)
- ans.push_back(d);
- }
- cout << ans.size();
- sort(ans.begin(), ans.end());
- for (int i = 0; i < ans.size(); i++)
- cout << "\n" << ans[i];
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement