Submission #57064

#TimeUsernameProblemLanguageResultExecution timeMemory
57064cki86201Fences (JOI18_fences)C++11
100 / 100
225 ms3824 KiB
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <memory.h> #include <math.h> #include <assert.h> #include <queue> #include <map> #include <set> #include <string> #include <algorithm> #include <iostream> #include <functional> #include <unordered_map> using namespace std; typedef pair<int, int> pii; typedef long long ll; #define Fi first #define Se second #define pb(x) push_back(x) #define szz(x) (int)x.size() #define rep(i, n) for(int i=0;i<n;i++) #define all(x) x.begin(), x.end() typedef tuple<int, int, int> t3; struct point { double x, y; point(){} point(double x, double y) : x(x), y(y) {} point operator-(point a) { return point(x - a.x, y - a.y); } point operator+(point a) { return point(x + a.x, y + a.y); } double operator*(point a) { return x * a.x + y * a.y; } point operator*(double a) { return point(x * a, y * a); } double operator/(point a) { return x * a.y - y * a.x; } double length() { return hypot(x, y); } }; vector <point> V; int N, S; point In[110][2]; const double EPS = 1e-9; inline int p1_in(double x) { return -S + EPS < x && x < S - EPS; } inline int seg1_in(double l1, double r1, double l2, double r2) { if(l1 > r1) swap(l1, r1); if(l2 > r2) swap(l2, r2); return max(l1, l2) + EPS < min(r1, r2); } int is_in(point a, point b) { if(fabs(a.x - b.x) <= EPS) { swap(a.x, a.y); swap(b.x, b.y); } if(fabs(a.x - b.x) <= EPS) { return p1_in(a.x) && p1_in(a.y); } if(fabs(a.y - b.y) <= EPS) { if(p1_in(a.y) && seg1_in(a.x, b.x, -S, S)) return 1; return 0; } double lx = (-S - a.x) / (b.x - a.x); double rx = (S - a.x) / (b.x - a.x); if(lx > rx) swap(lx, rx); double ly = (-S - a.y) / (b.y - a.y); double ry = (S - a.y) / (b.y - a.y); if(ly > ry) swap(ly, ry); double L = max({lx, ly, 0.0}); double R = min({rx, ry, 1.0}); if(L + EPS < R) return 1; return 0; } typedef pair<double, int> pdi; vector <point> PS; vector <pdi> E[50050]; int sign(double x) { if(fabs(x) <= EPS) return 0; return x > 0 ? 1 : -1; } int seg2_in(point a, point b, point c, point d) { return sign((b-a) / (c-a)) * sign((b-a) / (d-a)) == -1 && sign((d-c) / (a-c)) * sign((d-c) / (b-c)) == -1; } int meet(int a, int b) { point p1 = point(0, 0); point p2 = point(400 + sqrt(2), 1); return seg2_in(PS[a], PS[b], p1, p2); } void add_edge(int a, int b, double len = -1) { if(is_in(PS[a], PS[b])) return; int c = meet(a, b); if(len == -1) len = (PS[a] - PS[b]).length(); rep(u, 2) { E[a<<1^u].pb(pdi(len, b<<1^u^c)); E[b<<1^u^c].pb(pdi(len, a<<1^u)); } } double dis[50050]; double get_min(int x) { int s = x * 2, des = s + 1; priority_queue <pdi, vector<pdi>, greater<pdi> > pq; int N = szz(PS) * 2; rep(i, N) dis[i] = 1e9; dis[s] = 0; pq.push(pdi(0, s)); while(!pq.empty()) { pdi t = pq.top(); pq.pop(); if(dis[t.Se] != t.Fi) continue; if(t.Se == des) return t.Fi; for(pdi e : E[t.Se]) { if(e.Fi + t.Fi < dis[e.Se]) { dis[e.Se] = e.Fi + t.Fi; pq.push(pdi(dis[e.Se], e.Se)); } } } return dis[des]; } void solve(){ scanf("%d%d", &N, &S); for(int x : {-S, S}) for(int y : {-S, S}) PS.pb(point(x, y)); rep(i, N) { int l = szz(PS); rep(j, 2) { int x, y; scanf("%d%d", &x, &y); In[i][j] = point(x, y); PS.pb(In[i][j]); } add_edge(l, l+1, 0); } rep(i, szz(PS)) rep(j, i) add_edge(i, j); rep(i, 2*N+4) rep(j, N) { point a = In[j][0], b = In[j][1]; point p = PS[i]; if((p-a) * (b-a) > EPS && (p-b) * (a-b) > EPS) { double v = ((p-a) * (b-a)) / ((b-a) * (b-a)); point h = a + (b-a) * v; int ok = 1; rep(k, N) if(seg2_in(p, h, In[k][0], In[k][1])) { ok = 0; break; } // printf("p = (%.1f, %.1f), a = (%.1f, %.1f), b = (%.1f, %.1f), h = (%.1f, %.1f)\n", p.x, p.y, a.x, a.y, b.x, b.y, h.x, h.y); if(ok) { int z = szz(PS); PS.pb(h); add_edge(2 * j + 4, z, 0); add_edge(2 * j + 5, z, 0); add_edge(z, i); } } } double ans = 1e9; rep(i, 2*N+4) ans = min(ans, get_min(i)); printf("%.12f\n", ans); } int main(){ int Tc = 1; //scanf("%d", &Tc); for(int tc=1;tc<=Tc;tc++){ solve(); } return 0; }

Compilation message (stderr)

fences.cpp: In function 'void solve()':
fences.cpp:124:7: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
  scanf("%d%d", &N, &S);
  ~~~~~^~~~~~~~~~~~~~~~
fences.cpp:129:19: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
    int x, y; scanf("%d%d", &x, &y);
              ~~~~~^~~~~~~~~~~~~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...