Files
claoj/cpp/prevoi19_robots.cpp
T
2025-11-29 12:24:03 +07:00

110 lines
2.4 KiB
C++

// This solution is WIP. Not get full point.
#include <iostream>
#include <vector>
#include <algorithm>
#include <climits>
#include <set>
using namespace std;
typedef long long ll;
struct Point {
ll x, y;
};
ll manhattan(const Point &a, const Point &b) {
return abs(a.x - b.x) + abs(a.y - b.y);
}
bool isPossible(ll D, const vector<Point> &chargers, const Point &start, ll N) {
ll u0 = start.x + start.y;
ll v0 = start.x - start.y;
ll min_u = u0 - N;
ll max_u = u0 + N;
ll min_v = v0 - N;
ll max_v = v0 + N;
set<pair<ll, ll> > candidates;
candidates.insert({min_u, min_v});
candidates.insert({min_u, max_v});
candidates.insert({max_u, min_v});
candidates.insert({max_u, max_v});
for (const Point &c: chargers) {
ll cu = c.x + c.y;
ll cv = c.x - c.y;
vector<pair<ll, ll> > corners = {
{cu - D, cv - D}, {cu - D, cv + D},
{cu + D, cv - D}, {cu + D, cv + D}
};
for (auto [u, v]: corners) {
ll u_clamped = max(min_u, min(max_u, u));
ll v_clamped = max(min_v, min(max_v, v));
candidates.insert({u_clamped, v_clamped});
}
}
for (auto [u, v]: candidates) {
// if (u < min_u || u > max_u || v < min_v || v > max_v) continue;
if ((u + v) % 2 != 0) continue;
ll x = (u + v) / 2;
ll y = (u - v) / 2;
Point p = {x, y};
if (manhattan(p, start) > N) continue;
bool valid = true;
for (const Point &c: chargers) {
if (manhattan(p, c) < D) {
valid = false;
break;
}
}
if (valid) return true;
}
return false;
}
int main() {
ios_base::sync_with_stdio(false);
cin.tie(NULL);
int U;
ll N;
cin >> U >> N;
vector<Point> chargers(U);
for (int i = 0; i < U; i++) {
cin >> chargers[i].x >> chargers[i].y;
}
Point start;
cin >> start.x >> start.y;
ll max_dist = 0;
for (const Point &c: chargers) {
max_dist = max(max_dist, manhattan(start, c));
}
ll upper_bound = max_dist + N + 1;
ll left = 0;
ll right = upper_bound;
while (left <= right) {
ll mid = left + (right - left) / 2;
if (isPossible(mid, chargers, start, N)) {
left = mid + 1;
} else {
right = mid - 1;
}
}
cout << right << endl;
return 0;
}