제출 #973318

#제출 시각아이디문제언어결과실행 시간메모리
973318jakobrsPark (BOI16_park)C++17
0 / 100
186 ms50096 KiB
#include <algorithm> #include <bitset> #include <cmath> #include <iostream> #include <variant> #include <vector> template <typename... T> struct overloaded : public T... { using T::operator()...; }; template <typename... T> overloaded(T...) -> overloaded<T...>; struct UnionFind { std::vector<int> parent; UnionFind(int n) : parent(n, -1) {} auto find(int idx) -> int { if (parent[idx] < 0) return idx; else return parent[idx] = find(parent[idx]); } auto unite(int l, int r) -> bool { l = find(l); r = find(r); if (l == r) return false; if (-parent[l] < -parent[r]) std::swap(l, r); parent[l] += parent[r]; parent[r] = l; return true; } }; int main() { int n, m; std::cin >> n >> m; int w, h; std::cin >> w >> h; struct Tree { int x, y, r; }; auto trees = std::vector<Tree>(n); for (auto &tree : trees) std::cin >> tree.x >> tree.y >> tree.r; auto answers = std::vector<std::bitset<4>>(m); struct Event { struct Tree { int u, v; }; struct Query { int c; int id; }; double time; std::variant<Tree, Query> data; auto operator<(const Event &rhs) const -> bool { return time < rhs.time; } }; auto events = std::vector<Event>{}; auto left = n + 0; auto bottom = n + 1; auto right = n + 2; auto top = n + 3; for (int i = 0; i < trees.size(); i++) { for (int j = i + 1; j < trees.size(); j++) { // sqrt(dx^2 + dy^2) - r1 - r2 auto dx = trees[j].x - trees[i].x; auto dy = trees[j].y - trees[i].y; auto r1 = trees[i].r; auto r2 = trees[j].r; auto dist = std::sqrt(dx * dx + dy * dy); auto time = dist - r1 - r2; events.push_back(Event{ .time = time, .data = {Event::Tree{i, j}}, }); } // edges auto [x, y, r] = trees[i]; events.push_back(Event{ .time = double(x - r), .data = {Event::Tree{i, left}}, }); events.push_back(Event{ .time = double(w - x - r), .data = {Event::Tree{i, right}}, }); events.push_back(Event{ .time = double(y - r), .data = {Event::Tree{i, bottom}}, }); events.push_back(Event{ .time = double(h - y - r), .data = {Event::Tree{i, top}}, }); } for (int i = 0; i < m; i++) { int r, c; std::cin >> r >> c; events.push_back(Event{ .time = double(2 * r) - 1e-5, .data = {Event::Query{c - 1, i}}, }); } std::sort(events.begin(), events.end()); auto dsu = UnionFind(n + 4); for (auto event : events) { auto visitor = overloaded{ [&](Event::Tree data) { dsu.unite(data.u, data.v); }, [&](Event::Query data) { auto [c, i] = data; std::bitset<4> can_reach; for (int d = 0; d < 4; d++) { can_reach[d] = true; for (int x = 0; x < 4; x++) { for (int y = 0; y < 4; y++) { auto x_between = (c < x && x <= d) || (d < x && x <= c); auto y_between = (c < y && y <= d) || (d < y && y <= c); if (x_between && !y_between && dsu.find(n + x) == dsu.find(n + y)) { can_reach[d] = false; goto next; } } } next:; } answers[i] = can_reach; }}; std::visit(visitor, event.data); } for (auto x : answers) { for (int i = 0; i < 4; i++) if (x[i]) std::cout << i + 1; std::cout << '\n'; } }

컴파일 시 표준 에러 (stderr) 메시지

park.cpp: In function 'int main()':
park.cpp:80:21: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<main()::Tree>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   80 |   for (int i = 0; i < trees.size(); i++) {
      |                   ~~^~~~~~~~~~~~~~
park.cpp:81:27: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<main()::Tree>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   81 |     for (int j = i + 1; j < trees.size(); j++) {
      |                         ~~^~~~~~~~~~~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...