QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#313470 | #7846. Glacier Travel | supepapupu | AC ✓ | 2ms | 4012kb | C++17 | 9.1kb | 2024-01-24 19:40:07 | 2024-01-24 19:40:09 |
Judging History
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'