QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#313470#7846. Glacier TravelsupepapupuAC ✓2ms4012kbC++179.1kb2024-01-24 19:40:072024-01-24 19:40:09

Judging History

你现在查看的是最新测评结果

  • [2024-01-24 19:40:09]
  • 评测
  • 测评结果:AC
  • 用时:2ms
  • 内存:4012kb
  • [2024-01-24 19:40:07]
  • 提交

answer

// ????????
#include <bits/stdc++.h>

#define x first
#define y second
#define el '\n'
using namespace std;
typedef pair<double, double> pdd;

const int N = 1e5 + 10;
const double eps = 1e-8;
const double pi = acos(-1);

pdd operator+ (const pdd &a, const pdd &b) {
    return {a.x + b.x, a.y + b.y};
}

pdd operator- (const pdd &a, const pdd &b) {
    return {a.x - b.x, a.y - b.y};
}

pdd operator* (const pdd &a, const double &b) {
    return {a.x * b, a.y * b};
}

pdd operator/ (const pdd &a, const double &b) {
    return {a.x / b, a.y / b};
}

double operator* (const pdd &a, const pdd &b) {
    return a.x * b.x + a.y * b.y;
}

double operator^ (const pdd &a, const pdd &b) {
    return a.x * b.y - a.y * b.x;
}

void read(pdd &a) {
    scanf("%lf%lf", &a.x, &a.y);
}

void print(const pdd &a) {
    printf("%.10lf %.10lf\n", a.x, a.y);
}

struct Line {
    pdd st, ed;
};

struct Circle {
    pdd p;
    double r;
};

int sign(const double &a) {
    if (fabs(a) < eps) return 0;
    if (a > 0) return 1;
    return -1;
}

int dcmp(const double &a, const double &b) {
    if (fabs(a - b) < eps) return 0;
    if (a > b) return 1;
    return -1;
}

double area(const pdd &a, const pdd &b, const pdd &c) {
    return (b - a) ^ (c - a);
}

double len(const pdd &a) {
    return hypot(a.x, a.y);
}

double get_dis(const pdd &a, const pdd &b) {
    return hypot(a.x - b.x, a.y - b.y);
}

// ???????
pdd projection(const pdd &p, const pdd &a, const pdd &b) {
    auto v = b - a;
    return a + v * (v * (p - a) / (v * v));
}

// ?????????
pdd reflection(const pdd &p, const pdd &a, const pdd &b) {
    auto u = projection(p, a, b);
    return p + (u - p) * 2;
}

// ????????
int point_vector_relation(const pdd &p, const pdd &a, const pdd &b) {
    if (!sign(area(a, b, p))) {
        auto ap = p - a, bp = p - b;
        if (sign(ap * bp) <= 0) return 0; // ?????
        if (get_dis(a, p) > get_dis(b, p)) return 1; // ?????
        return 2; // ?????
    }
    if (area(a, b, p) > 0) return 3; // ?????????
    return 4; // ?????????
}

// ????
double get_angle(const Line &a) {
    return atan2(a.ed.y - a.st.y, a.ed.x - a.st.x);
}

// ????? ???????
double get_angle(const Line &a, const Line &b) {
    return get_angle(a) - get_angle(b);
}

// ?????????
int line_line_relation(const Line &a, const Line &b) {
    if (!sign((a.ed - a.st) ^ (b.ed - b.st))) {
        if (!sign(area(a.st, a.ed, b.st))) return 0; // ??
        return 1; // ??
    }
    if (!sign((a.ed - a.st) * (b.ed - b.st))) return 2; // ??
    return 3; // ??
}

// ???????
bool segment_intersection(const pdd &a1, const pdd &a2, const pdd &b1, const pdd &b2) {
    if (line_line_relation({a1, a2}, {b1, b2}) == 1) return 0;
    else if (line_line_relation({a1, a2}, {b1, b2}) == 0) {
        if (point_vector_relation(a1, b1, b2) == 0 || point_vector_relation(a2, b1, b2) == 0) return 1;
        if (point_vector_relation(b1, a1, a2) == 0 || point_vector_relation(b2, a1, a2) == 0) return 1;
        return 0;
    }
    double c1 = (a2 - a1) ^ (b1 - a1), c2 = (a2 - a1) ^ (b2 - a1);
    double c3 = (b2 - b1) ^ (a2 - b1), c4 = (b2 - b1) ^ (a1 - b1);
    return sign(c1) * sign(c2) <= 0 && sign(c3) * sign(c4) <= 0;
}

// ??????
pdd get_line_intersection(const pdd &p, const pdd &v, const pdd &q, const pdd &w) {
    auto u = p - q;
    double t = w ^ u / (v ^ w);
    return p + v * t;
}

pdd get_line_intersection(const Line &a, const Line &b) {
    return get_line_intersection(a.st, a.ed - a.st, b.st, b.ed - b.st);
}

// ??????
double distance_to_line(const pdd &p, const pdd &a, const pdd &b) {
    auto v1 = b - a, v2 = p - a;
    return fabs(v1 ^ v2 / hypot(v1.x, v1.y));
}

// ??????
double distance_to_segment(const pdd &p, const pdd &a, const pdd &b) {
    if (!dcmp(a.x, b.x) && !dcmp(a.y, b.y)) return get_dis(p, a);
    auto v1 = b - a, v2 = p - a, v3 = p - b;
    if (sign(v1 * v2) < 0) return hypot(v2.x, v2.y);
    if (sign(v1 * v3) > 0) return hypot(v3.x, v3.y);
    return distance_to_line(p, a, b);
}

// ???????
double segment_distance_to_segment(const pdd &a1, const pdd &a2, const pdd &b1, const pdd &b2) {
    if (segment_intersection(a1, a2, b1, b2)) return 0;
    double ret = min(distance_to_segment(a1, b1, b2), distance_to_segment(a2, b1, b2));
    ret = min(ret, distance_to_segment(b1, a1, a2));
    ret = min(ret, distance_to_segment(b2, a1, a2));
    return ret;
}

// ?????
double polygon_area(pdd p[], int n) {
    double s = 0;
    for (int i = 1; i + 1 < n; ++i)
        s += area(p[0], p[i], p[i + 1]);
    return s / 2;
}


// ????????
bool convex(pdd p[], int n) {
    for (int i = 0; i < n; ++i) {
        if (sign(area(p[i], p[(i + 1) % n], p[(i + 2) % n])) * sign(area(p[(i + 1) % n], p[(i + 2) % n], p[(i + 3) % n])) < 0) {
            return 0;
        }
    }
    return 1;
}

// ??????????
int in_polygon(const pdd &p, pdd q[], int n) {
    srand(time(0));
    for (int i = 0; i < n; ++i) {
        if (point_vector_relation(p, q[i], q[(i + 1) % n]) == 0) return 1; //??????
    }
    double angle = (double)rand() / RAND_MAX * 2 * pi;
    pdd d = {1e8 * cos(angle), 1e8 * sin(angle)};
    int cnt = 0;
    for (int i = 0; i < n; ++i) {
        cnt += segment_intersection(p, p + d, q[i], q[(i + 1) % n]);
    }
    if (cnt & 1) return 2; // ??????
    return 0; // ??????
}

// ????
int get_quadrant(const pdd &a) {
    if (a.x > 0 && a.y >= 0) return 1;
    else if (a.y > 0) return 2;
    else if (a.x < 0) return 3;
    return 4;
}

bool cmp(const pdd &a, const pdd &b) {
    int qa = get_quadrant(a), qb = get_quadrant(b);
    if (qa != qb) return qa < qb;
    return (a ^ b) > 0;
}

// ??
int stk[N];
bool used[N];
double convex_hull(pdd q[], int n) {
    sort(q, q + n);
    int top = 0;
    for (int i = 0; i < n; ++i) {
        while (top >= 2 && area(q[stk[top - 1]], q[stk[top]], q[i]) > 0) { // > ???????? >=?????
            if (area(q[stk[top - 1]], q[stk[top]], q[i]) > 0)
                used[stk[top--]] = 0;
            else --top;
        }
        used[i] = 1;
        stk[++top] = i;
    }
    used[0] = 0;
    for (int i = n - 1; i >= 0; --i) {
        if (used[i]) continue;
        while (top >= 2 && area(q[stk[top - 1]], q[stk[top]], q[i]) > 0) --top;
        stk[++top] = i;
    }
    // y??x?????????????
    /*
    printf("%d\n", top - 1);
    pdd mn = {1e8, 1e8};
    int v;
    for (int i = 1; i < top; ++i) {
        if (dcmp(q[stk[i]].y, mn.y) < 0)
            mn = q[stk[i]], v = i;
        else if (dcmp(q[stk[i]].y, mn.y) == 0)
            if (dcmp(q[stk[i]].x, mn.x) < 0)
                mn = q[stk[i]], v = i;
    }
    printf("%.0lf %.0lf\n", q[stk[v]].x, q[stk[v]].y);
    for (int i = v - 1; ; --i) {
        if (i < 1) i += top - 1;
        if (i == v) break;
        printf("%.0lf %.0lf\n", q[stk[i]].x, q[stk[i]].y);
    }
    */
    double ret = 0; // ????
    for (int i = 2; i <= top; ++i) ret += get_dis(q[stk[i]], q[stk[i - 1]]);
    return ret;
}

// ????
bool cmpl(const Line &a, const Line &b) {
    double A = get_angle(a), B = get_angle(b);
    if (!dcmp(A, B)) return area(a.st, a.ed, b.ed) < 0;
    return A < B;
}

bool on_right(const Line &a, const Line &b, const Line &c) {
    auto o = get_line_intersection(b, c);
    return sign(area(a.st, a.ed, o)) <= 0;
}

int q[N];
pdd ans[N];

double half_plane_intersection(Line line[], int n) {
    // sort(line, line + n, cmpl);
    int hh = 0, tt = -1;
    for (int i = 0; i < n; ++i) {
        if (i && !dcmp(get_angle(line[i]), get_angle(line[i - 1]))) continue;
        while (hh + 1 <= tt && on_right(line[i], line[q[tt]], line[q[tt - 1]])) --tt;
        while (hh + 1 <= tt && on_right(line[i], line[q[hh]], line[q[hh + 1]])) ++hh;
        q[++tt] = i;
    }
    while (hh + 1 <= tt && on_right(line[q[hh]], line[q[tt]], line[q[tt - 1]])) --tt;
    while (hh + 1 <= tt && on_right(line[q[tt]], line[q[hh]], line[q[hh + 1]])) ++hh;
    
    q[++tt] = q[hh];
    int k = 0;
    for (int i = hh; i < tt; ++i) {
        ans[k ++] = get_line_intersection(line[q[i]], line[q[i + 1]]);
    }
    double ret = 0;
    for (int i = 1; i + 1 < k; ++i) {
        ret += area(ans[0], ans[i], ans[i + 1]);
    }
    return ret / 2;
}

double min_dis(Line a, Line b) {
    pdd da = a.ed - a.st, db = b.ed - b.st;
    pdd d = db - da;
    return distance_to_segment(a.st, b.st, b.st + d);
}

int main() {
    ios::sync_with_stdio(0); cin.tie(0);
    double s; cin >> s;
    int n; cin >> n;
    vector<pdd> q(n);
    for (int i = 0; i < n; ++i) cin >> q[i].x >> q[i].y;
    int i = 0, j = 0;
    double d = 0;
    while (i + 1 < n && d + get_dis(q[i], q[i + 1]) <= s) d += get_dis(q[i], q[i + 1]), ++i;
    pdd x = q[i] + (q[i + 1] - q[i]) / len(q[i + 1] - q[i]) * (s - d), y = q[0];
    double ans = get_dis(q[0], x);
    while (i + 1 < n) {
        double t = min(get_dis(x, q[i + 1]), get_dis(y, q[j + 1]));
        if (!dcmp(t, get_dis(x, q[i + 1]))) {
            pdd p = y + (q[j + 1] - q[j]) / len(q[j + 1] - q[j]) * t;
            ans = min(ans, min_dis((Line){x, q[i + 1]}, (Line){y, p}));
            x = q[++i], y = p;
        } else {
            pdd p = x + (q[i + 1] - q[i]) / len(q[i + 1] - q[i]) * t;
            ans = min(ans, min_dis((Line){x, p}, (Line){y, q[j + 1]}));
            x = p, y = q[++j];
        }
    }
    cout << fixed << setprecision(10) << ans << el;
}

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 100
Accepted
time: 0ms
memory: 3900kb

input:

5
4
20 0
10 0
10 10
0 10

output:

3.5355339059

result:

ok found '3.53553', expected '3.53553', error '0.00000'

Test #2:

score: 0
Accepted
time: 0ms
memory: 3964kb

input:

3.16227766
9
-2 4
2 4
3 1
4 4
5 1
6 4
10 2
6 1
7 4

output:

1.0000000000

result:

ok found '1.00000', expected '1.00000', error '0.00000'

Test #3:

score: 0
Accepted
time: 0ms
memory: 3964kb

input:

20
5
9 38
36 16
-5 36
-24 15
30 37

output:

2.2935957604

result:

ok found '2.29360', expected '2.29360', error '0.00000'

Test #4:

score: 0
Accepted
time: 0ms
memory: 3976kb

input:

10
40
17 18
12 -5
12 -16
-10 16
7 -15
18 -18
19 15
-19 1
-18 11
-8 -12
-17 -12
5 -12
-15 -8
-10 -10
-4 4
-2 -3
15 17
-2 -9
-13 7
-12 17
15 -3
-19 -14
6 6
14 -5
-10 -15
17 -16
-11 15
9 -6
10 8
19 -1
12 -6
-18 2
14 17
9 -7
-8 -3
7 11
-12 -14
-19 4
-1 15
-17 16

output:

0.0000000000

result:

ok found '0.00000', expected '0.00000', error '-0.00000'

Test #5:

score: 0
Accepted
time: 0ms
memory: 3988kb

input:

10
40
10 11
11 15
6 -16
-18 4
10 10
-10 16
-17 11
2 6
-6 -9
17 -7
-7 -5
10 -18
-9 9
-14 10
19 -3
-14 -3
15 -5
-3 16
-10 14
-9 -12
10 -18
10 -4
-9 -11
11 -2
9 2
12 15
2 -17
-8 -16
19 7
-19 -2
-17 7
16 -9
6 -6
8 -18
15 9
17 2
-19 12
-15 -9
1 -15
19 -12

output:

0.3442144373

result:

ok found '0.34421', expected '0.34421', error '0.00000'

Test #6:

score: 0
Accepted
time: 2ms
memory: 3984kb

input:

1000
4000
-720538 -681604
667325 347504
-911397 -962007
-264075 -858319
49605 149209
964851 361021
-397274 28661
-460607 -273701
104862 -136807
-803899 -693703
-974 -337735
323678 -209811
-745617 -358684
-984333 603546
722843 -444579
701511 -255784
-676477 -836480
998942 -227888
-502059 -438394
9641...

output:

0.0445047435

result:

ok found '0.04450', expected '0.04450', error '0.00000'

Test #7:

score: 0
Accepted
time: 2ms
memory: 4012kb

input:

1000
4000
703 909
500 496
-214 628
914 -44
-330 -238
-1424 -1426
347 1420
332 -1417
877 1678
-1390 819
-921 525
121 -923
-851 -859
512 -151
765 -109
416 -1529
-269 667
475 -234
-708 300
1917 -1935
-909 1342
1141 -696
-272 1295
1908 -1124
-898 -1225
1608 630
-1937 1246
-255 1021
-1005 -1650
-1595 -39...

output:

0.0381857100

result:

ok found '0.03819', expected '0.03819', error '0.00000'

Test #8:

score: 0
Accepted
time: 0ms
memory: 3952kb

input:

40
3
100 0
0 100
0 0

output:

15.3073372946

result:

ok found '15.30734', expected '15.30734', error '0.00000'

Test #9:

score: 0
Accepted
time: 0ms
memory: 3980kb

input:

48.2842712475
4
-10 -10
10 10
-10 10
10 -10

output:

0.0000000000

result:

ok found '0.00000', expected '0.00000', error '-0.00000'