제출 #100466

#제출 시각아이디문제언어결과실행 시간메모리
100466JPN20Fences (JOI18_fences)C++17
51 / 100
188 ms484 KiB
#include <bits/stdc++.h> using namespace std; struct Point { double px, py; }; struct Segment { Point p1, p2; }; double dst(Point a1, Point a2) { return sqrtl((a1.px - a2.px) * (a1.px - a2.px) + (a1.py - a2.py) * (a1.py - a2.py)); } double crs(Point a1, Point a2) { return a1.px * a2.px + a1.py * a2.py; } double dot(Point a1, Point a2) { return a1.px * a2.py - a1.py * a2.px; } int ccw(Point a1, Point a2, Point a3) { Point a4 = Point{a2.px - a1.px, a2.py - a1.py}; Point a5 = Point{a3.px - a2.px, a3.py - a2.py}; double I = dot(a4, a5); if (I < -1e-8) return -1; if (I > 1e-8) return 1; return 0; } bool its(Segment a1, Segment a2) { int cnt1 = 0; if (ccw(a1.p1, a1.p2, a2.p1) * ccw(a1.p1, a1.p2, a2.p2) == -1) cnt1++; if (ccw(a2.p1, a2.p2, a1.p1) * ccw(a2.p1, a2.p2, a1.p2) == -1) cnt1++; if (cnt1 == 2) return true; return false; } Point projection(Point a1, Segment a2) { if (dst(a2.p1, a2.p2) < 1e-5) return a2.p1; long double DD = fabs(dot(Point{a2.p2.px - a2.p1.px, a2.p2.py - a2.p1.py}, Point{a1.px - a2.p1.px, a1.py - a2.p1.py})) / dst(a2.p1, a2.p2); Point V = Point{a2.p2.py - a2.p1.py, a2.p2.px - a2.p1.px}; V.px /= dst(a2.p1, a2.p2) / DD; V.py /= dst(a2.p1, a2.p2) / DD; Point W1 = Point{a1.px + 2.0 * V.px, a1.py - 2.0 * V.py}; if (its(Segment{a1, W1}, a2) == true) return Point{a1.px + V.px, a1.py - V.py}; return Point{a1.px - V.px, a1.py + V.py}; } pair<Point, Point> dst1(Point a1, Point a2) { return make_pair(a1, a2); } pair<Point, Point> dst2(Point a1, Segment a2) { long double V1 = dst(a1, a2.p1); long double V2 = dst(a1, a2.p2); long double V3 = fabs(dot(Point{a2.p2.px - a2.p1.px, a2.p2.py - a2.p1.py}, Point{a1.px - a2.p1.px, a1.py - a2.p1.py})) / dst(a2.p1, a2.p2); if (crs(Point{a2.p2.px - a2.p1.px, a2.p2.py - a2.p1.py}, Point{a1.px - a2.p1.px, a1.py - a2.p1.py}) < 0) V3 = 1e9; if (crs(Point{a2.p1.px - a2.p2.px, a2.p1.py - a2.p2.py}, Point{a1.px - a2.p2.px, a1.py - a2.p2.py}) < 0) V3 = 1e9; if (V1 <= V2 && V1 <= V3) return make_pair(a1, a2.p1); if (V2 <= V1 && V2 <= V3) return make_pair(a1, a2.p2); return make_pair(a1, projection(a1, a2)); } pair<Point, Point> dst3(Segment a1, Point a2) { pair<Point, Point> D = dst2(a2, a1); return make_pair(D.second, D.first); } pair<Point, Point> dst4(Segment a1, Segment a2) { pair<Point, Point> D1 = dst2(a1.p1, a2); long double V1 = dst(D1.first, D1.second); pair<Point, Point> D2 = dst2(a1.p2, a2); long double V2 = dst(D2.first, D2.second); pair<Point, Point> D3 = dst3(a1, a2.p1); long double V3 = dst(D3.first, D3.second); pair<Point, Point> D4 = dst3(a1, a2.p2); long double V4 = dst(D4.first, D4.second); if (V1 <= V2 && V1 <= V3 && V1 <= V4) return D1; if (V2 <= V1 && V2 <= V3 && V2 <= V4) return D2; if (V3 <= V1 && V3 <= V2 && V3 <= V4) return D3; return D4; } int N; double S; Segment L[10]; pair<Point, Point> G[10][10]; bool used[10][10]; long double CONSTANT = 0.1145141919810893; int main() { cin >> N >> S; for (int i = 4; i < 4 + N; i++) cin >> L[i].p1.px >> L[i].p1.py >> L[i].p2.px >> L[i].p2.py; L[0].p1.px = -S; L[0].p1.py = -S; L[0].p2 = L[0].p1; L[1].p1.px = -S; L[1].p1.py = +S; L[1].p2 = L[1].p1; L[2].p1.px = +S; L[2].p1.py = +S; L[2].p2 = L[2].p1; L[3].p1.px = +S; L[3].p1.py = -S; L[3].p2 = L[3].p1; for (int i = 0; i < 4 + N; i++) { for (int j = 0; j < 4 + N; j++) { if (i == j) continue; G[i][j] = dst4(L[i], L[j]); used[i][j] = true; vector<int> E1 = {0, 1, 2, 3, 0, 1}; vector<int> E2 = {1, 2, 3, 0, 2, 3}; for (int k = 0; k < 6; k++) { if (its(Segment{G[i][j].first, G[i][j].second}, Segment{L[E1[k]].p1, L[E2[k]].p1}) == true) used[i][j] = false; } } } long double ans = 1e9; for (int i = 1; i < (1 << (4 + N)); i++) { vector<int> vec; for (int j = 0; j < 4 + N; j++) { if ((i / (1 << j)) % 2 == 1) vec.push_back(j); } int s = vec[0]; do { if (vec[0] != s) break; bool ok = true; for (int j = 0; j < (int)vec.size(); j++) { int s1 = vec[j], s2 = vec[(j + 1) % vec.size()]; if (used[s1][s2] == false) { ok = false; break; } } if (ok == false) continue; vector<Point>tup; for (int j = 0; j < (int)vec.size(); j++) { int s1 = vec[j], s2 = vec[(j + 1) % vec.size()]; tup.push_back(G[s1][s2].first); tup.push_back(G[s1][s2].second); } long double D = 0; int cnt1 = 0; for (int j = 0; j < (int)tup.size(); j++) { Point s1 = tup[j], s2 = tup[(j + 1) % tup.size()]; if (s1.px < CONSTANT && CONSTANT < s2.px) { long double Y = (CONSTANT - s1.px) * s2.py + (s2.px - CONSTANT) * s1.py; Y /= (s2.px - s1.px); if (Y > 0) cnt1++; } if (s2.px < CONSTANT && CONSTANT < s1.px && s1.py > 0) { long double Y = (CONSTANT - s2.px) * s1.py + (s1.px - CONSTANT) * s2.py; Y /= (s1.px - s2.px); if (Y > 0) cnt1--; } if (j % 2 == 0) D += dst(s1, s2); } if (cnt1 == 1) ans = min(ans, D); }while(next_permutation(vec.begin(), vec.end())); } printf("%.12Lf\n", ans); return 0; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...