Submission #671708

#TimeUsernameProblemLanguageResultExecution timeMemory
671708havingfun854Mobile (BOI12_mobile)C++11
100 / 100
739 ms43804 KiB
// https://oj.uz/problem/view/BOI12_mobile #include <bits/stdc++.h> using namespace std; #define forint(i, from, toinc) for (int i = from; i <= toinc; ++i) #define sq(x) (x)*(x) #define all(x) x.begin(), x.end() void fio() { ios::sync_with_stdio(0); cin.tie(0); #ifdef USEFILE freopen("mobile.in", "r", stdin); freopen("mobile.out", "w", stdout); #endif } /* some observations: if we have 2 towers with the same x, (x, y1) and (x, y2), we only need to keep the one with the smallest abs y value, let's say |y1| <= |y2|, then we can safely forget (x, y2), because for any point on the x axis, it will always be closer (<=) to (x, y1) than to (x, y2). we do a simple binary search on distance d to see if all points between [0,L] can be covered by d. when trying to see if the segments covers the entire [0,len] range, we do NOT have to sort the segments, because if a later one (one corresponding to a tower with greater x value) connects with the current range while a earlier one does not, we know from geometry that the later one will extend further to the right as well, making not considering the earlier one inconsequential. but this time, don't break when seeing a gap. */ struct Point { int x,y; }; struct Range { double from, to; bool operator<(const Range &o) const { return from == o.from ? to > o.to : from < o.from; // same from rank the one with the larger to first } }; int tcnt; // tower count vector<Point> towers; int len; // all points on (0,0) to (len,0) to the towers vector<Range> ranges; int rcnt; void debug() { cerr << "highway from (0,0) to (" << len << ",0)" << endl; cerr << tcnt << " towers:"; forint(i, 0, tcnt-1) { cerr << " " << towers[i].x << "," << towers[i].y; } cerr << endl; cerr << rcnt << " ranges:"; forint(i, 0, rcnt-1) { cerr << " [" << ranges[i].from << "," << ranges[i].to << "]"; } cerr << endl; } void rdata() { cin >> tcnt >> len; int lastx, lasty; // lasty >= 0 cin >> lastx >> lasty; lasty = abs(lasty); forint(i, 1, tcnt-1) { int x, y; cin >> x >> y; if (x != lastx) { towers.push_back({lastx, lasty}); lastx = x; lasty = abs(y); } else if (abs(y) < abs(lasty)) { lasty = abs(y); } if (i == tcnt-1) { towers.push_back({lastx, lasty}); } } tcnt = (int)towers.size(); } bool can_cover(double d) { ranges.clear(); forint(i, 0, tcnt-1) { double x = towers[i].x; double y = towers[i].y; if (d > y) { double dx = sqrt(sq(d) - sq(y)); if (x-dx > len || x+dx < 0) continue; ranges.push_back({x-dx, x+dx}); } } rcnt = (int)ranges.size(); // sort(all(ranges)); #ifdef DEBUG debug(); #endif double right = 0; forint(i, 0, rcnt-1) { if (ranges[i].from <= right) { right = max(ranges[i].to, right); if (right >= len) break; } } bool res = right >= len; #ifdef DEBUG cerr << "d=" << d << " can" << (res ? "" : "not") << " cover all" << endl; #endif return res; } inline double d2(int i, double x) // tower i to (x,0) { return sq(towers[i].x - x) + sq(towers[i].y); } int main() { fio(); rdata(); #ifdef DEBUG debug(); #endif double dends2 = d2(0, 0); dends2 = max(dends2, d2(0, len)); dends2 = max(dends2, d2(tcnt-1, 0)); dends2 = max(dends2, d2(tcnt-1, len)); double dmax = sqrt(dends2); double d = dmax+1; for (double step = dmax; step > 1e-4; step /= 2) { while (d-step > 0 && can_cover(d-step)) { d -= step; } } cout << fixed << setprecision(3) << d << '\n'; return 0; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...