Submission #305617

#TimeUsernameProblemLanguageResultExecution timeMemory
305617youngyojunFences (JOI18_fences)C++17
100 / 100
907 ms1272 KiB
#include <bits/stdc++.h> #define pb push_back #define eb emplace_back #define sz(V) ((int)(V).size()) #define allv(V) ((V).begin()),((V).end()) #define befv(V) ((V)[(sz(V)-2)]) #define sorv(V) sort(allv(V)) #define revv(V) reverse(allv(V)) #define univ(V) (V).erase(unique(allv(V)),(V).end()) #define clv(V) (V).clear() #define upmin(a,b) (a)=min((a),(b)) #define upmax(a,b) (a)=max((a),(b)) #define rb(x) ((x)&(-(x))) #define INF (0x3f3f3f3f) #define INFLL (0x3f3f3f3f3f3f3f3fll) using namespace std; typedef long long ll; typedef long double ld; typedef pair<int, int> pii; typedef pair<ld, ld> pdd; const ld EPS = ld(1e-8)/2; bool isZero(ld n) { return abs(n) < EPS; } bool isSame(ld a, ld b) { return isZero(a-b); } ld pw(ld n) { return n*n; } ld size(pdd a) { return sqrt(pw(a.first) + pw(a.second)); } int sign(ld n) { return isZero(n) ? 0 : (0 < n ? 1 : -1); } struct Vec { Vec(ld x = 0, ld y = 0, ld z = 0) : x(x), y(y), z(z) {} ld x, y, z; bool operator == (const Vec& t) const { return isZero(x - t.x) && isZero(y - t.y) && isZero(z - t.z); } Vec operator + (const Vec& t) const { return Vec(x+t.x, y+t.y, z+t.z); } Vec operator - (const Vec& t) const { return Vec(x-t.x, y-t.y, z-t.z); } Vec operator * (const ld& t) const { return Vec(x*t, y*t, z*t); } Vec operator / (const ld& t) const { return Vec(x/t, y/t, z/t); } Vec operator * (const Vec& t) const { return Vec(y*t.z - z*t.y, z*t.x - x*t.z, x*t.y - y*t.x); } ld operator / (const Vec& t) const { return x*t.x + y*t.y + z*t.z; } ld len() const { return sqrt(x*x + y*y + z*z); } ld pwlen() const { return x*x + y*y + z*z; } void norm() { const ld L = len(); if(!isZero(L)) *this = *this / L; } }; typedef vector<Vec> Cec; ld ccw(const Vec& a, const Vec& b, const Vec& c) { return ((b-a) * (c-a)).len(); } // a -- b -- c : True, Otherwise : False bool isbet(Vec a, Vec b, Vec c) { if(a == b || b == c) return true; ld x = (b-a).pwlen(), y = (c-b).pwlen(), z = (c-a).pwlen(); if(!isZero(x*y*4 - pw(x+y-z))) return false; if(a.x < c.x && (b.x < a.x-EPS || c.x+EPS < b.x)) return false; if(a.x > c.x && (b.x < c.x-EPS || a.x+EPS < b.x)) return false; if(a.y < c.y && (b.y < a.y-EPS || c.y+EPS < b.y)) return false; if(a.y > c.y && (b.y < c.y-EPS || a.y+EPS < b.y)) return false; return true; } bool isco(Vec a, Vec b, Vec c) { return isZero(ccw(a, b, c)); } pair<Vec, bool> intersect(Vec a, Vec b, Vec c, Vec d) { Vec u = b-a, v = d-c, z = c-a, vz = v*z, vu = v*u; if(isZero(vu.len())) return {Vec(), false}; return {a + u * (vz.len() / vu.len() * sign(vz / vu)), true}; } Vec project(Vec a, Vec b, Vec c) { b.norm(); return b * ((c-a) / b) + a; } const int MAXN = 205; double D[MAXN*2][MAXN*2]; Vec A[MAXN], B[MAXN]; int SPI[MAXN]; const int CPV[28][5] = { {1, 0}, {1, 1}, {1, 2}, {1, 3}, {2, 0, 1}, {2, 1, 2}, {2, 2, 3}, {2, 3, 0}, {2, 1, 0}, {2, 2, 1}, {2, 3, 2}, {2, 0, 3}, {3, 0, 1, 2}, {3, 1, 2, 3}, {3, 2, 3, 0}, {3, 3, 0, 1}, {3, 2, 1, 0}, {3, 3, 2, 1}, {3, 0, 3, 2}, {3, 1, 0, 3}, {4, 0, 1, 2, 3}, {4, 1, 2, 3, 0}, {4, 2, 3, 0, 1}, {4, 3, 0, 1, 2}, {4, 3, 2, 1, 0}, {4, 2, 1, 0, 3}, {4, 1, 0, 3, 2}, {4, 0, 3, 2, 1} }; Vec BP[4], CP[4]; Vec lv; double Ans; int N, C; bool isp(Vec a, Vec b) { if(a == b) return true; Vec ret; bool chk; for(int i = 0; i < 4; i++) { tie(ret, chk) = intersect(a, b, BP[i], BP[(i+1)%4]); if(chk && isbet(BP[i], ret, BP[(i+1)%4]) && isbet(a, ret, b)) return false; } return true; } bool ispl(Vec a, Vec b) { if(a == b) return false; Vec ret; bool chk; tie(ret, chk) = intersect(a, b, Vec(), lv); return chk && EPS < ret.x && EPS < ret.y && isbet(a, ret, b); } void upd(Cec V, ld &reta, ld &retb) { ld ret = 0; bool flag = false; for(int i = 1, n = sz(V); i < n; i++) { if(!isp(V[i-1], V[i])) return; flag ^= ispl(V[i-1], V[i]); ret += (V[i] - V[i-1]).len(); } if(flag) upmin(retb, ret); else upmin(reta, ret); } void upd1(Vec a, Vec b, Vec c, ld &reta, ld &retb) { Vec p = project(b, c-b, a); if(!isbet(b, p, c)) return; upd(Cec{a, p}, reta, retb); } void f(Vec ps, Vec pe, Vec qs, Vec qe, ld &reta, ld &retb, bool iss) { reta = retb = INFLL; if(!iss) { upd(Cec{ps, qs}, reta, retb); upd(Cec{ps, qe}, reta, retb); upd(Cec{pe, qs}, reta, retb); upd(Cec{pe, qe}, reta, retb); upd1(ps, qs, qe, reta, retb); upd1(pe, qs, qe, reta, retb); upd1(qs, ps, pe, reta, retb); upd1(qe, ps, pe, reta, retb); } for(int cpvi = 0, cpvsz; cpvi < 28; cpvi++) { cpvsz = CPV[cpvi][0]; if(iss && cpvsz < 3) continue; Cec PV, QV; PV.eb(ps); PV.eb(pe); QV.eb(qs); QV.eb(qe); { Vec p = project(ps, pe-ps, CP[CPV[cpvi][1]]); if(isbet(ps, p, pe)) PV.eb(p); } { Vec p = project(qs, qe-qs, CP[CPV[cpvi][cpvsz]]); if(isbet(qs, p, qe)) QV.eb(p); } Vec ph, qh; { ld pl = INFLL; for(auto &p : PV) { ld t = (p - CP[CPV[cpvi][1]]).len(); if(pl <= t) continue; ph = p; pl = t; } } { ld ql = INFLL; for(auto &p : QV) { ld t = (p - CP[CPV[cpvi][cpvsz]]).len(); if(ql <= t) continue; qh = p; ql = t; } } Cec Path; Path.eb(ph); for(int i = 1; i <= cpvsz; i++) Path.eb(CP[CPV[cpvi][i]]); Path.eb(qh); upd(Path, reta, retb); } } int main() { ios_base::sync_with_stdio(0); cin.tie(0); srand(20010610); lv.x = ld(rand() % 708790 + 337) / ld(rand() % 900 + 755); lv.y = ld(rand() % 632048 + 469) / ld(rand() % 908 + 147); cin >> N >> C; for(int i = 1; i <= N; i++) cin >> A[i].x >> A[i].y >> B[i].x >> B[i].y; { ld CEPS = ld(1e-5); BP[0] = Vec(ld(C) - CEPS, ld(C) - CEPS); BP[1] = Vec(ld(C) - CEPS, ld(-C) + CEPS); BP[2] = Vec(ld(-C) + CEPS, ld(-C) + CEPS); BP[3] = Vec(ld(-C) + CEPS, ld(C) - CEPS); CP[0] = Vec(C, C); CP[1] = Vec(C, -C); CP[2] = Vec(-C, -C); CP[3] = Vec(-C, C); } { ld CEPS = ld(1e-4)/2; for(int i = N; i; i--) { Vec a = A[i], b = B[i]; if(!ispl(a, b)) continue; Vec p = intersect(a, b, Vec(), lv).first; Vec v = p-a; v.norm(); v = v * CEPS; N++; A[N] = a; B[N] = p-v; A[i] = p+v; B[i] = b; SPI[i] = N; } } for(int i = 1; i <= N; i++) for(int j = i; j <= N; j++) { ld a, b; f(A[i], B[i], A[j], B[j], a, b, i == j); D[i*2][j*2] = D[i*2-1][j*2-1] = D[j*2][i*2] = D[j*2-1][i*2-1] = a; D[i*2-1][j*2] = D[i*2][j*2-1] = D[j*2-1][i*2] = D[j*2][i*2-1] = b; } for(int i = 1; i <= N; i++) { D[i*2][i*2] = D[i*2-1][i*2-1] = 0; int t = SPI[i]; if(t) D[i*2][t*2-1] = D[i*2-1][t*2] = D[t*2][i*2-1] = D[t*2-1][i*2] = 0; } for(int k = 1; k <= N*2; k++) for(int i = 1; i <= N*2; i++) for(int j = 1; j <= N*2; j++) upmin(D[i][j], D[i][k] + D[k][j]); Ans = ld(C) * 8; for(int i = 1; i <= N; i++) upmin(Ans, D[i*2][i*2-1]); printf("%.10lf\n", Ans); return 0; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...