提出 #27486895


ソースコード 拡げる

#include <algorithm>
#include <cassert>
#include <iostream>
#include <map>
#include <string>
#include <vector>
using namespace std;

// reference : http://www.ivis.co.jp/text/20111102.pdf
struct SurrealNumber {
  using S = SurrealNumber;
  using i64 = long long;

  // p / 2^q の形で保持
  i64 p, q;
  SurrealNumber(i64 _p = 0, i64 _q = 0) : p(_p), q(_q) {}
  friend ostream& operator<<(ostream& os, const SurrealNumber& r) {
    os << r.p;
    if (r.q != 0) os << " / " << (i64{1} << r.q);
    return os;
  }

  static S normalize(S s) {
    if (s.p != 0) {
      while (s.p % 2 == 0 and s.q != 0) s.p /= 2, s.q--;
    } else {
      s.q = 0;
    }
    return {s.p, s.q};
  }

  // 加算・減算
  friend S operator+(const S& l, const S& r) {
    i64 cq = max(l.q, r.q);
    i64 cp = (l.p << (cq - l.q)) + (r.p << (cq - r.q));
    return normalize(S{cp, cq});
  }
  friend S operator-(const S& l, const S& r) {
    i64 cq = max(l.q, r.q);
    i64 cp = (l.p << (cq - l.q)) - (r.p << (cq - r.q));
    return normalize(S{cp, cq});
  }
  S& operator+=(const S& r) { return (*this) = (*this) + r; }
  S& operator-=(const S& r) { return (*this) = (*this) - r; }

  // 大小関係
  friend bool operator<(const S& l, const S& r) { return (r - l).p > 0; }
  friend bool operator<=(const S& l, const S& r) { return (r - l).p >= 0; }
  friend bool operator>(const S& l, const S& r) { return (l - r).p > 0; }
  friend bool operator>=(const S& l, const S& r) { return (l - r).p >= 0; }
  friend bool operator==(const S& l, const S& r) { return (l - r).p == 0; }
  friend bool operator!=(const S& l, const S& r) { return (l - r).p != 0; }

  // 左右の子を返す関数
  pair<S, S> child() const {
    if (p == 0) return {-1, 1};
    if (q == 0 and p > 0) return {S{p * 2 - 1, 1}, p + 1};
    if (q == 0 and p < 0) return {p - 1, S{p * 2 + 1, 1}};
    return {(*this) - S{1, q + 1}, (*this) + S{1, q + 1}};
  }

  S larger() const {
    S root = 0;
    while ((*this) >= root) root = root.child().second;
    return root;
  }
  S smaller() const {
    S root = 0;
    while ((*this) <= root) root = root.child().first;
    return root;
  }
  friend S reduce(const S& l, const S& r) {
    assert(l < r);
    S root = 0;
    while (l >= root or root >= r) {
      auto [lr, rr] = root.child();
      root = (r <= root ? lr : rr);
    }
    return root;
  }
};

template <typename Game, typename F>
struct PartisanGame {
  using Games = vector<Game>;
  using S = SurrealNumber;

  map<Game, S> mp;
  F f;

  PartisanGame(const F& _f) : f(_f) {}

  S zero() const { return S{0}; }

  S get(Game g) {
    if (mp.count(g)) return mp[g];
    return mp[g] = _get(g);
  }

 private:
  S _get(Game g) {
    Games gl, gr;
    tie(gl, gr) = f(g);
    if (gl.empty() and gr.empty()) return 0;
    vector<S> l, r;
    for (auto& cg : gl) l.push_back(get(cg));
    for (auto& cg : gr) r.push_back(get(cg));
    S sl, sr;
    if (!l.empty()) sl = *max_element(begin(l), end(l));
    if (!r.empty()) sr = *min_element(begin(r), end(r));
    if (r.empty()) return sl.larger();
    if (l.empty()) return sr.smaller();
    assert(sl < sr);
    return reduce(sl, sr);
  }
};

template <typename Game, typename F>
struct ImpartialGame {
  using Games = vector<Game>;
  using N = long long;

  map<Games, N> mp;
  F f;

  ImpartialGame(const F& _f) : f(_f) {}

  N zero() const { return N{0}; }

  N get(Game g) {
    if (mp.count(g)) return mp[g];
    return mp[g] = _get(g);
  }

 private:
  N _get(Game g) {
    Games gs = f(g);
    if (gs.empty()) return 0;
    vector<N> ns;
    for (auto& cg : gs) ns.push_back(get(cg));
    sort(begin(gs), end(gs));
    gs.erase(unique(begin(gs), end(gs)), end(gs));
    for (int i = 0; i < (int)gs.size(); i++) {
      if (gs[i] != i) return i;
    }
    return (int)gs.size();
  }
};

#define rep(i, n) for (int i = 0; i < (int)(n); i++)

int main() {
  using Game = vector<long long>;

  // 白 1 黒 2
  auto f = [&](Game g) {
    vector<Game> L, R;
    rep(i, g.size()) {
      if (g[i] == 1) {
        g[i] = 0;
        R.push_back(g);
        g[i] = 1;
        if (i and g[i - 1] == 0) {
          g[i] = 0, g[i - 1] = 1;
          L.push_back(g);
          g[i] = 1, g[i - 1] = 0;
        }
      }
      if (g[i] == 2) {
        g[i] = 0;
        L.push_back(g);
        g[i] = 2;
        if (i and g[i - 1] == 0) {
          g[i] = 0, g[i - 1] = 2;
          R.push_back(g);
          g[i] = 2, g[i - 1] = 0;
        }
      }
    }
    return make_pair(L, R);
  };

  int N;
  cin >> N;
  vector<string> board(N);
  for (auto& b : board) cin >> b;

  PartisanGame<Game, decltype(f)> pg(f);
  auto ans = pg.zero();

  rep(j, N) {
    Game g(N);
    rep(i, N) {
      if (board[i][j] == 'W') g[i] = 1;
      if (board[i][j] == 'B') g[i] = 2;
    }
    ans += pg.get(g);

    //rep(_, N) cerr << g[_] << " ";
    //cerr << " : ";
    //cerr << pg.get(g) << endl;
  }

  cout << (ans > 0 ? "Takahashi" : "Snuke") << "\n";
}

提出情報

提出日時
問題 H - Advance or Eat
ユーザ Nyaan
言語 C++ (GCC 9.2.1)
得点 600
コード長 5154 Byte
結果 AC
実行時間 23 ms
メモリ 4296 KiB

ジャッジ結果

セット名 Sample All
得点 / 配点 0 / 0 600 / 600
結果
AC × 3
AC × 109
セット名 テストケース
Sample example0.txt, example1.txt, example2.txt
All 000.txt, 001.txt, 002.txt, 003.txt, 004.txt, 005.txt, 006.txt, 007.txt, 008.txt, 009.txt, 010.txt, 011.txt, 012.txt, 013.txt, 014.txt, 015.txt, 016.txt, 017.txt, 018.txt, 019.txt, 020.txt, 021.txt, 022.txt, 023.txt, 024.txt, 025.txt, 026.txt, 027.txt, 028.txt, 029.txt, 030.txt, 031.txt, 032.txt, 033.txt, 034.txt, 035.txt, 036.txt, 037.txt, 038.txt, 039.txt, 040.txt, 041.txt, 042.txt, 043.txt, 044.txt, 045.txt, 046.txt, 047.txt, 048.txt, 049.txt, 050.txt, 051.txt, 052.txt, 053.txt, 054.txt, 055.txt, 056.txt, 057.txt, 058.txt, 059.txt, 060.txt, 061.txt, 062.txt, 063.txt, 064.txt, 065.txt, 066.txt, 067.txt, 068.txt, 069.txt, 070.txt, 071.txt, 072.txt, 073.txt, 074.txt, 075.txt, 076.txt, 077.txt, 078.txt, 079.txt, 080.txt, 081.txt, 082.txt, 083.txt, 084.txt, 085.txt, 086.txt, 087.txt, 088.txt, 089.txt, 090.txt, 091.txt, 092.txt, 093.txt, 094.txt, 095.txt, 096.txt, 097.txt, 098.txt, 099.txt, 100.txt, 101.txt, 102.txt, 103.txt, 104.txt, 105.txt, example0.txt, example1.txt, example2.txt
ケース名 結果 実行時間 メモリ
000.txt AC 21 ms 3948 KiB
001.txt AC 17 ms 4104 KiB
002.txt AC 12 ms 3900 KiB
003.txt AC 20 ms 4008 KiB
004.txt AC 3 ms 3472 KiB
005.txt AC 15 ms 3812 KiB
006.txt AC 2 ms 3556 KiB
007.txt AC 2 ms 3456 KiB
008.txt AC 20 ms 4140 KiB
009.txt AC 5 ms 3704 KiB
010.txt AC 10 ms 4004 KiB
011.txt AC 4 ms 3556 KiB
012.txt AC 7 ms 3668 KiB
013.txt AC 13 ms 4136 KiB
014.txt AC 13 ms 3924 KiB
015.txt AC 13 ms 4024 KiB
016.txt AC 23 ms 4040 KiB
017.txt AC 9 ms 3764 KiB
018.txt AC 12 ms 3844 KiB
019.txt AC 11 ms 3784 KiB
020.txt AC 8 ms 3656 KiB
021.txt AC 5 ms 3616 KiB
022.txt AC 2 ms 3500 KiB
023.txt AC 16 ms 3964 KiB
024.txt AC 14 ms 3936 KiB
025.txt AC 19 ms 3956 KiB
026.txt AC 9 ms 3916 KiB
027.txt AC 5 ms 3676 KiB
028.txt AC 2 ms 3504 KiB
029.txt AC 2 ms 3508 KiB
030.txt AC 2 ms 3504 KiB
031.txt AC 2 ms 3592 KiB
032.txt AC 2 ms 3552 KiB
033.txt AC 2 ms 3600 KiB
034.txt AC 2 ms 3428 KiB
035.txt AC 2 ms 3604 KiB
036.txt AC 2 ms 3496 KiB
037.txt AC 3 ms 3600 KiB
038.txt AC 2 ms 3508 KiB
039.txt AC 2 ms 3460 KiB
040.txt AC 5 ms 3576 KiB
041.txt AC 2 ms 3612 KiB
042.txt AC 2 ms 3516 KiB
043.txt AC 2 ms 3508 KiB
044.txt AC 2 ms 3604 KiB
045.txt AC 2 ms 3600 KiB
046.txt AC 2 ms 3612 KiB
047.txt AC 2 ms 3432 KiB
048.txt AC 3 ms 3624 KiB
049.txt AC 2 ms 3572 KiB
050.txt AC 2 ms 3648 KiB
051.txt AC 3 ms 3492 KiB
052.txt AC 3 ms 3672 KiB
053.txt AC 3 ms 3644 KiB
054.txt AC 4 ms 3672 KiB
055.txt AC 4 ms 3576 KiB
056.txt AC 6 ms 3604 KiB
057.txt AC 10 ms 3784 KiB
058.txt AC 10 ms 3788 KiB
059.txt AC 8 ms 3632 KiB
060.txt AC 7 ms 3688 KiB
061.txt AC 10 ms 3792 KiB
062.txt AC 20 ms 4240 KiB
063.txt AC 15 ms 4008 KiB
064.txt AC 21 ms 4296 KiB
065.txt AC 19 ms 4216 KiB
066.txt AC 17 ms 4204 KiB
067.txt AC 15 ms 4152 KiB
068.txt AC 2 ms 3628 KiB
069.txt AC 2 ms 3656 KiB
070.txt AC 2 ms 3472 KiB
071.txt AC 2 ms 3656 KiB
072.txt AC 2 ms 3576 KiB
073.txt AC 2 ms 3560 KiB
074.txt AC 2 ms 3604 KiB
075.txt AC 2 ms 3668 KiB
076.txt AC 2 ms 3564 KiB
077.txt AC 2 ms 3564 KiB
078.txt AC 2 ms 3616 KiB
079.txt AC 2 ms 3612 KiB
080.txt AC 2 ms 3564 KiB
081.txt AC 3 ms 3588 KiB
082.txt AC 2 ms 3632 KiB
083.txt AC 2 ms 3552 KiB
084.txt AC 2 ms 3608 KiB
085.txt AC 2 ms 3560 KiB
086.txt AC 4 ms 3692 KiB
087.txt AC 9 ms 3496 KiB
088.txt AC 5 ms 3760 KiB
089.txt AC 4 ms 3508 KiB
090.txt AC 3 ms 3484 KiB
091.txt AC 7 ms 3644 KiB
092.txt AC 5 ms 3688 KiB
093.txt AC 4 ms 3568 KiB
094.txt AC 4 ms 3504 KiB
095.txt AC 3 ms 3628 KiB
096.txt AC 14 ms 3760 KiB
097.txt AC 9 ms 3724 KiB
098.txt AC 9 ms 3672 KiB
099.txt AC 16 ms 3808 KiB
100.txt AC 14 ms 3944 KiB
101.txt AC 10 ms 3796 KiB
102.txt AC 9 ms 3764 KiB
103.txt AC 17 ms 4036 KiB
104.txt AC 10 ms 3748 KiB
105.txt AC 7 ms 3736 KiB
example0.txt AC 2 ms 3576 KiB
example1.txt AC 2 ms 3416 KiB
example2.txt AC 2 ms 3604 KiB