답안 #973318

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
973318 2024-05-01T18:24:53 Z jakobrs Park (BOI16_park) C++17
0 / 100
186 ms 50096 KB
#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';
  }
}

Compilation message

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++) {
      |                         ~~^~~~~~~~~~~~~~
# 결과 실행 시간 메모리 Grader output
1 Correct 178 ms 50088 KB Output is correct
2 Incorrect 186 ms 50096 KB Output isn't correct
3 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Incorrect 65 ms 5312 KB Output isn't correct
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 178 ms 50088 KB Output is correct
2 Incorrect 186 ms 50096 KB Output isn't correct
3 Halted 0 ms 0 KB -