Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <algorithm>
- #include <iostream>
- #include <sstream>
- #include <queue>
- #include <deque>
- #include <stack>
- #include <map>
- #include <vector>
- #include <string>
- #include <set>
- #include <cstdio>
- #include <cmath>
- #include <ctime>
- #include <cstdlib>
- #include <cstring>
- #include <cassert>
- #define sz(a) (int)a.size()
- #define all(a) a.begin(), a.end()
- #define rall(a) a.rbegin(), a.rend()
- #define llong long long
- #define zero(a) fabs(a) < 1e-9
- #define resz(a, n) a.clear(), a.resize(n)
- #define same(a, n) memset(a, n, sizeof(a))
- #define make(a, b) make_pair(a, b)
- using namespace std;
- const int MAXN = 405;
- const int MAXM = 1005;
- const int INF = 1000000;
- struct Point {
- double x, y, ang;
- Point(double X = 0, double Y = 0): x(X), y(Y) {}
- void center(int cx, int cy) {
- x -= cx, y -= cy;
- }
- bool operator < (const Point &q) const {
- return ang < q.ang;
- }
- };
- int n, m;
- Point p[MAXN];
- bool equal(double a, double b) {
- return abs(a - b) < 1e-9;
- }
- double dist(Point a, Point b) {
- return sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y));
- }
- void order(Point &a, Point &b) {
- if (b.y < a.y)
- swap(a, b);
- }
- bool belong(Point a, Point b, Point c) {
- return (a.y <= c.y && c.y <= b.y && ((a.x <= c.x && c.x <= b.x) || (b.x <= c.x && c.x <= a.x)));
- }
- Point intersect(Point a, Point b, Point c, Point d) {
- if (equal(c.x, d.x)) {
- swap(a, c);
- swap(b, d);
- }
- order(a, b), order(c, d);
- if (equal(c.x, d.x)) {
- if (equal(a.x, c.x) && (belong(a, b, c) || belong(a, b, d)))
- return Point(-INF);
- return Point(INF);
- }
- double t2 = (d.y - c.y) / (d.x - c.x), o2 = c.y - t2 * c.x;
- if (equal(a.x, b.x)) {
- Point ret(a.x, t2 * a.x + o2);
- if (belong(a, b, ret) && belong(c, d, ret))
- return ret;
- return Point(INF);
- }
- double t1 = (b.y - a.y) / (b.x - a.x), o1 = a.y - t1 * a.x, ix = (o2 - o1) / (t1 - t2);
- if (equal(t1, t2) && equal(o1, o2))
- return Point(-INF);
- Point ret(ix, t1 * ix + o1);
- if (belong(a, b, ret) && belong(c, d, ret))
- return ret;
- return Point(INF);
- }
- bool inside(Point q) {
- for (int i = 0; i < n; i++) {
- Point a = p[i], b = p[(i + 1) % n], c(b.x - a.x, b.y - a.y), d(q.x - a.x, q.y - a.y);
- if (c.x * d.y - d.x * c.y < 0)
- return false;
- }
- return true;
- }
- int main() {
- int cx = INF, cy = INF;
- scanf("%d", &n);
- for (int i = 0; i < n; i++) {
- scanf("%lf %lf", &p[i].x, &p[i].y);
- if (p[i].x < cx)
- cx = p[i].x, cy = p[i].y;
- else if (p[i].x == cx && p[i].y < cy)
- cy = p[i].y;
- }
- for (int i = 0; i < n; i++) {
- p[i].center(cx, cy);
- if (p[i].x == 0 && p[i].y == 0)
- p[i].ang = 4;
- else
- p[i].ang = atan2(p[i].y, p[i].x);
- }
- sort(p, p + n);
- scanf("%d", &m);
- for (int i = 0; i < m; i++) {
- Point a, b;
- scanf("%lf %lf %lf %lf", &a.x, &a.y, &b.x, &b.y);
- bool good = true;
- a.center(cx, cy), b.center(cx, cy);
- Point i1(INF), i2(INF);
- for (int j = 0; j < n; j++) {
- Point now = intersect(a, b, p[j], p[(j + 1) % n]);
- if (equal(now.x, INF))
- continue;
- if (equal(now.x, -INF)) {
- good = false;
- break;
- }
- if (equal(i1.x, INF) || (equal(i1.x, now.x) && equal(i1.y, now.y)))
- i1 = now;
- else
- i2 = now;
- }
- if (!good) {
- printf("%.6lf\n", 0.0);
- continue;
- }
- bool u = inside(a), v = inside(b);
- if (u && v)
- printf("%.6lf\n", dist(a, b));
- else if (!equal(i2.x, INF))
- printf("%.6lf\n", dist(i1, i2));
- else if (!equal(i1.x, INF) && (u || v)) {
- if (!u)
- swap(a, b);
- printf("%.6lf\n", dist(i1, a));
- }
- else
- printf("%.6lf\n", 0.0);
- }
- return 0;
- }
Add Comment
Please, Sign In to add comment