제출 #1329119

#제출 시각아이디문제언어결과실행 시간메모리
1329119avighnaCircle Passing (EGOI24_circlepassing)C++20
100 / 100
354 ms51508 KiB
#include <bits/stdc++.h>

using namespace std;

const int inf = 1e9;

int main() {
  ios::sync_with_stdio(false);
  cin.tie(nullptr);

  int n, m, q;
  cin >> n >> m >> q;

  vector<int> tele;
  set<int> pads;
  for (int i = 0, k; i < m; ++i) {
    cin >> k;
    tele.push_back(k), tele.push_back(k + n);
    pads.insert(k), pads.insert(k + n);
  }
  sort(tele.begin(), tele.end());

  auto left = [&](int x) {
    auto it = lower_bound(tele.begin(), tele.end(), x);
    if (it == tele.begin()) {
      return *--tele.end();
    }
    return *--it;
  };
  auto right = [&](int x) {
    auto it = upper_bound(tele.begin(), tele.end(), x);
    if (it == tele.end()) {
      return *tele.begin();
    }
    return *it;
  };

  auto direct = [&](int x, int y) { return min((y - x + 2 * n) % (2 * n), (x - y + 2 * n) % (2 * n)); };

  while (q--) {
    int x, y;
    cin >> x >> y;
    int ans = direct(x, y); // if we don't teleport
    for (auto &[x, y] : vector<pair<int, int>>({{x, y}, {y, x}})) {
      if (pads.contains(x)) {
        // teleport x => x+n
        int u = (x + n) % (2 * n);
        ans = min(ans, 1 + direct(u, y));
      }
      // or walk to the left and teleport
      int l = left(x);
      int lt = (l + n) % (2 * n);
      ans = min(ans, direct(x, l) + 1 + direct(lt, y));
      // or walk to the right and teleport
      int r = right(x);
      int rt = (r + n) % (2 * n);
      int v1 = direct(x, r), v2 = 1, v3 = direct(rt, y);
      ans = min(ans, direct(x, r) + 1 + direct(rt, y));
    }
    cout << ans << '\n';
  }
}
#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...