QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#114220#2293. Boredom BusterHgCl2WA 239ms8312kbC++144.8kb2023-06-21 15:57:252023-06-21 15:57:26

Judging History

你现在查看的是最新测评结果

  • [2023-08-10 23:21:45]
  • System Update: QOJ starts to keep a history of the judgings of all the submissions.
  • [2023-06-21 15:57:26]
  • 评测
  • 测评结果:WA
  • 用时:239ms
  • 内存:8312kb
  • [2023-06-21 15:57:25]
  • 提交

answer

#include <algorithm>
#include <array>
#include <cstddef>
#include <cstdint>
#include <iostream>
#include <list>
#include <utility>
#include <vector>

namespace {
using std::cin;
using std::cout;
using std::endl;
using std::int64_t;
using std::size_t;

namespace base {
template <typename T, size_t... sizes>
struct NestedArray {};

template <typename T, size_t size, size_t... sizes>
struct NestedArray<T, size, sizes...> {
  using Type = std::array<typename NestedArray<T, sizes...>::Type, size>;
};

template <typename T>
struct NestedArray<T> {
  using Type = T;
};

template <typename T, size_t... sizes>
using Array = typename NestedArray<T, sizes...>::Type;
}  // namespace base

using base::Array;

const int kMaxN = 1.0e5 + 5;
Array<int, kMaxN> pos, link;
Array<bool, kMaxN> vis;
std::list<int> list;
Array<std::list<int>::iterator, kMaxN> it;

std::pair<int, int> revealCards(int x, int y) {
  cout << "? " << x << " " << y << endl;
  int a, b;
  cin >> a >> b;
  return {a, b};
}
}  // namespace

std::vector<int> guessCards(int n) {
  std::fill_n(pos.begin() + 1, n, 0);
  int half = n / 2;

  for (int i = 1; i <= n; i += 2) {
    auto res = revealCards(i, i + 1);
    int x = res.first, y = res.second;
    if (pos[x]) x += half;
    pos[x] = i;
    if (pos[y]) y += half;
    pos[y] = i + 1;
    link[x] = y, link[y] = x;
  }

  std::fill_n(vis.begin() + 1, n, false);
  for (int i = 1; i <= n; i++) list.emplace_back(i), it[i] = --list.end();
  auto switcher = [half](int x) { return x <= half ? x + half : x - half; };
  auto lower = [half](int x) { return x <= half ? x : x - half; };
  auto remove = [](int x) { list.erase(it[x]), vis[x] = true; };

  auto check = [](const std::pair<int, int> &p, int x, int y) {
    return p.first == x && p.second == y || p.first == y && p.second == x;
  };

  std::vector<std::pair<int, int>> edge, circle;

  while (!list.empty()) {
    int u = *list.begin(), v = link[u];

    if (v == switcher(u)) {
      remove(u), remove(v);
      continue;
    }

    while (true) {
      int sv = switcher(v);

      if (vis[sv]) {
        edge.emplace_back(u, v);
        remove(u), remove(v);
        break;
      }

      int w = link[sv], su = switcher(u);

      if (w == su) {
        circle.emplace_back(u, v);
        remove(u), remove(su), remove(v), remove(sv);
        break;
      }

      int lu = lower(u), lv = lower(v), lw = lower(w);
      auto res = revealCards(pos[u], pos[sv]);

      if (check(res, lu, lv)) {
        remove(v), remove(w);
        link[u] = sv, link[sv] = u;
        u = switcher(w), v = link[u];
        if (vis[u]) break;
      } else if (check(res, lu, lw)) {
        remove(v), remove(sv);
        std::swap(pos[sv], pos[w]);
        link[u] = w, link[w] = u;
        v = w;
      } else if (check(res, lv, lv)) {
        remove(u), remove(v), remove(sv), remove(w);
        std::swap(pos[u], pos[v]);
        u = switcher(w), v = link[u];
        if (vis[u]) break;
      } else if (check(res, lv, lw)) {
        remove(u), remove(sv);
        std::swap(pos[u], pos[v]), std::swap(pos[sv], pos[w]);
        link[v] = w, link[w] = v;
        u = v, v = w;
      } else {
        __builtin_unreachable();
      }
    }
  }

  while (edge.size() > 1) {
    auto e1 = edge.back();
    edge.pop_back();
    auto e2 = edge.back();
    edge.pop_back();
    int a = e1.first, b = e1.second, c = e2.first, d = e2.second;
    int la = lower(a), lb = lower(b), lc = lower(c), ld = lower(d);
    auto res = revealCards(pos[a], pos[c]);

    if (check(res, la, lc)) {
      edge.emplace_back(a, c);
    } else if (check(res, la, ld)) {
      std::swap(pos[c], pos[d]);
      edge.emplace_back(a, d);
    } else if (check(res, lb, lc)) {
      std::swap(pos[a], pos[b]);
      edge.emplace_back(b, c);
    } else if (check(res, lb, ld)) {
      std::swap(pos[a], pos[b]), std::swap(pos[c], pos[d]);
      edge.emplace_back(b, d);
    } else {
      __builtin_unreachable();
    }
  }

  if (!edge.empty()) circle.emplace_back(edge.back());

  for (const auto &e : circle) {
    int u = e.first, v = e.second, su = switcher(u), sv = switcher(v),
        lu = lower(u), lv = lower(v), type = 0;

    while (true) {
      auto res = revealCards(pos[u], pos[type ? v : su]);

      if (res.first == res.second) {
        if (res.first == lu) {
          if (type) std::swap(pos[v], pos[su]);
        } else if (res.first == lv) {
          std::swap(pos[u], pos[sv]);
          if (!type) std::swap(pos[v], pos[su]);
        } else {
          __builtin_unreachable();
        }

        break;
      }

      type ^= 1;
    }
  }

  std::vector<int> ans(n);
  for (int i = 1; i <= n; i++) ans[pos[i] - 1] = lower(i);
  return ans;
}

int main() {
  int n;
  cin >> n;
  guessCards(n);
  return 0;
}

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 0
Wrong Answer
time: 239ms
memory: 8312kb

input:

100000
14243 13962
6948 22252
19244 19543
38903 11287
38236 8431
8855 44004
32239 28696
4163 13408
34466 26456
34636 16506
17476 19659
41596 45165
44174 8145
32853 13855
13860 32650
39829 40439
26857 16321
28351 11239
14823 35976
18843 47987
13886 18541
1370 15381
16164 41277
10418 10077
1431 40902
...

output:

? 1 2
? 3 4
? 5 6
? 7 8
? 9 10
? 11 12
? 13 14
? 15 16
? 17 18
? 19 20
? 21 22
? 23 24
? 25 26
? 27 28
? 29 30
? 31 32
? 33 34
? 35 36
? 37 38
? 39 40
? 41 42
? 43 44
? 45 46
? 47 48
? 49 50
? 51 52
? 53 54
? 55 56
? 57 58
? 59 60
? 61 62
? 63 64
? 65 66
? 67 68
? 69 70
? 71 72
? 73 74
? 75 76
? 77 ...

result:

wrong answer format  Unexpected end of file - token expected