제출 #164726

#제출 시각아이디문제언어결과실행 시간메모리
164726xiaowuc1Park (BOI16_park)C++17
100 / 100
476 ms38808 KiB
#include <algorithm> #include <bitset> #include <cassert> #include <chrono> #include <cstring> #include <iomanip> #include <iostream> #include <map> #include <queue> #include <random> #include <set> #include <stack> #include <vector> using namespace std; // BEGIN NO SAD #define rep(i, a, b) for(int i = a; i < (b); ++i) #define trav(a, x) for(auto& a : x) #define all(x) x.begin(), x.end() #define sz(x) (int)(x).size() typedef vector<int> vi; // END NO SAD typedef long long ll; typedef pair<int, int> pii; typedef pair<ll, ll> pll; typedef pair<pii, int> query; // <radius, entrance>, idx typedef long double ld; typedef pair<double, pii> event; // distance, <a, b> int par[2005]; const int NORTH = 2000; const int EAST = 2001; const int SOUTH = 2002; const int WEST = 2003; int find(int x) { return par[x] == x ? x : (par[x] = find(par[x])); } void merge(int x, int y) { par[find(x)] = find(y); } query queries[100005]; string ret[100005]; int n, q; int maxX, maxY; int x[2005]; int y[2005]; int r[2005]; bool canReach(int a, int b) { // BL BR TR TL assert(min(a, b) >= 1 && max(a, b) <= 4); if(a == b) return true; if(a > b) swap(a, b); if(a == 1 && b == 2) { return find(SOUTH) != find(NORTH) && find(SOUTH) != find(WEST) && find(SOUTH) != find(EAST); } if(a == 1 && b == 3) { if(find(WEST) == find(SOUTH)) return false; if(find(WEST) == find(EAST)) return false; if(find(SOUTH) == find(NORTH)) return false; if(find(EAST) == find(NORTH)) return false; return true; } if(a == 1 && b == 4) { if(find(WEST) == find(NORTH)) return false; if(find(WEST) == find(SOUTH)) return false; if(find(WEST) == find(EAST)) return false; return true; } if(a == 2 && b == 3) { if(find(EAST) == find(WEST)) return false; if(find(EAST) == find(NORTH)) return false; if(find(EAST) == find(SOUTH)) return false; return true; } if(a == 2 && b == 4) { if(find(EAST) == find(SOUTH)) return false; if(find(NORTH) == find(SOUTH)) return false; if(find(WEST) == find(EAST)) return false; if(find(NORTH) == find(WEST)) return false; return true; } if(a == 3 && b == 4) { if(find(NORTH) == find(WEST)) return false; if(find(NORTH) == find(EAST)) return false; if(find(NORTH) == find(SOUTH)) return false; return true; } assert(false); } void fillRet(int idx) { // query index for(int a = 1; a <= 4; a++) { if(canReach(queries[idx].first.second, a)) { ret[queries[idx].second] += to_string(a); } } } void solve() { cin >> n >> q >> maxX >> maxY; for(int i = 0; i <= WEST; i++) par[i] = i; for(int i = 0; i < n; i++) cin >> x[i] >> y[i] >> r[i]; for(int i = 0; i < q; i++) { cin >> queries[i].first.first >> queries[i].first.second; queries[i].first.first *= 2; queries[i].second = i; } sort(queries, queries+q); vector<event> events; for(int i = 0; i < n; i++) { events.push_back(event(maxY - y[i] - r[i], {NORTH, i})); events.push_back(event(y[i] - r[i], {SOUTH, i})); events.push_back(event(x[i] - r[i], {WEST, i})); events.push_back(event(maxX - x[i] - r[i], {EAST, i})); for(int j = 0; j < i; j++) { events.push_back(event(hypot(y[i] - y[j], x[i] - x[j]) - r[i] - r[j], {i, j})); } } sort(events.begin(), events.end()); int idx = 0; for(int i = 0; i < q; i++) { while(idx < sz(events) && events[idx].first < queries[i].first.first) { merge(events[idx].second.first, events[idx].second.second); idx++; } fillRet(i); } for(int i = 0; i < q; i++) cout << ret[i] << "\n"; } int main() { ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL); solve(); }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...