提出 #28887690


ソースコード 拡げる

#include <cassert>
#include <limits>
#include <type_traits>

// Dyadic rational, surreal numbers
template <class Int, class Uint = unsigned long long>
struct DyadicRational {
    Int integ;  // 整数部分
    Uint frac;  // 小数部分の分子

    static constexpr int FracLen = std::numeric_limits<Uint>::digits - 1;  // 2^63
    static constexpr Uint denom = Uint(1) << FracLen;  // 小数部分の分母

    DyadicRational(Int x = 0) : integ(x), frac(0) {
        static_assert(0 < FracLen and FracLen < std::numeric_limits<Uint>::digits, "FracLen value error");
        static_assert(std::is_signed<Int>::value == true, "Int must be signed");
    }
    static DyadicRational _construct(Int x, Uint frac_) {
        DyadicRational ret(x);
        ret.frac = frac_;
        return ret;
    }
    double to_double() const { return integ + double(frac) / denom; }

    // static DyadicRational from_rational(Int num, int lg_den);
    bool operator==(const DyadicRational &r) const { return integ == r.integ and frac == r.frac; }
    bool operator!=(const DyadicRational &r) const { return integ != r.integ or frac != r.frac; }
    bool operator<(const DyadicRational &r) const {
        return integ != r.integ ? integ < r.integ : frac < r.frac;
    }
    bool operator<=(const DyadicRational &r) const { return (*this == r) or (*this < r); }
    bool operator>(const DyadicRational &r) const { return r < *this; }
    bool operator>=(const DyadicRational &r) const { return r <= *this; }

    DyadicRational operator+(const DyadicRational &r) const {
        auto i = integ + r.integ;
        auto f = frac + r.frac;
        if (f >= denom) ++i, f -= denom; // overflow
        return DyadicRational::_construct(i, f);
    }
    DyadicRational operator-(const DyadicRational &r) const {
        auto i = integ - r.integ;
        auto f = frac - r.frac;
        if (f > denom) --i, f += denom; // overflow
        return DyadicRational::_construct(i, f);
    }
    DyadicRational operator-() const { return DyadicRational() - *this; }
    DyadicRational &operator+=(const DyadicRational &r) { return *this = *this + r; }

    DyadicRational right() const {
        if (frac == 0) {
            if (integ >= 0) {
                return DyadicRational(integ + 1);
            } else {
                return DyadicRational::_construct(integ, Uint(1) << (FracLen - 1));
            }
        }
        int d = __builtin_ctzll(frac);
        return DyadicRational::_construct(integ, frac ^ (Uint(1) << (d - 1)));
    }
    DyadicRational left() const {
        if (frac == 0) {
            if (integ <= 0) {
                return DyadicRational(integ - 1);
            } else {
                return DyadicRational::_construct(integ - 1, Uint(1) << (FracLen - 1));
            }
        }
        int d = __builtin_ctzll(frac);
        return DyadicRational::_construct(integ, frac ^ (Uint(3) << (d - 1)));
    }

    // Surreal number { l | r }
    static DyadicRational surreal(const DyadicRational &l, const DyadicRational &r) {
        assert(l < r);
        DyadicRational x(0);
        if (l.integ > 0) x = DyadicRational(l.integ);
        if (r.integ < 0) x = DyadicRational(r.integ);
        while (true) {
            if (x <= l) {
                x = x.right();
            } else if (x >= r) {
                x = x.left();
            } else {
                break;
            }
        }
        return x;
    }
    template <class OStream> friend OStream &operator<<(OStream &os, const DyadicRational &x) {
        return os << x.to_double();
    }
};
// using dyrational = DyadicRational<long long>;

#include <algorithm>
#include <array>
#include <bitset>
#include <cassert>
#include <chrono>
#include <cmath>
#include <complex>
#include <deque>
#include <forward_list>
#include <fstream>
#include <functional>
#include <iomanip>
#include <ios>
#include <iostream>
#include <limits>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <random>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <tuple>
#include <type_traits>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <vector>
using namespace std;
using lint = long long;
using pint = pair<int, int>;
using plint = pair<lint, lint>;
struct fast_ios { fast_ios(){ cin.tie(nullptr), ios::sync_with_stdio(false), cout << fixed << setprecision(20); }; } fast_ios_;
#define ALL(x) (x).begin(), (x).end()
#define FOR(i, begin, end) for(int i=(begin),i##_end_=(end);i<i##_end_;i++)
#define IFOR(i, begin, end) for(int i=(end)-1,i##_begin_=(begin);i>=i##_begin_;i--)
#define REP(i, n) FOR(i,0,n)
#define IREP(i, n) IFOR(i,0,n)
template <typename T, typename V>
void ndarray(vector<T>& vec, const V& val, int len) { vec.assign(len, val); }
template <typename T, typename V, typename... Args> void ndarray(vector<T>& vec, const V& val, int len, Args... args) { vec.resize(len), for_each(begin(vec), end(vec), [&](T& v) { ndarray(v, val, args...); }); }
template <typename T> bool chmax(T &m, const T q) { return m < q ? (m = q, true) : false; }
template <typename T> bool chmin(T &m, const T q) { return m > q ? (m = q, true) : false; }
int floor_lg(long long x) { return x <= 0 ? -1 : 63 - __builtin_clzll(x); }
template <typename T1, typename T2> pair<T1, T2> operator+(const pair<T1, T2> &l, const pair<T1, T2> &r) { return make_pair(l.first + r.first, l.second + r.second); }
template <typename T1, typename T2> pair<T1, T2> operator-(const pair<T1, T2> &l, const pair<T1, T2> &r) { return make_pair(l.first - r.first, l.second - r.second); }
template <typename T> vector<T> sort_unique(vector<T> vec) { sort(vec.begin(), vec.end()), vec.erase(unique(vec.begin(), vec.end()), vec.end()); return vec; }
template <typename T> int arglb(const std::vector<T> &v, const T &x) { return std::distance(v.begin(), std::lower_bound(v.begin(), v.end(), x)); }
template <typename T> int argub(const std::vector<T> &v, const T &x) { return std::distance(v.begin(), std::upper_bound(v.begin(), v.end(), x)); }
template <typename T> istream &operator>>(istream &is, vector<T> &vec) { for (auto &v : vec) is >> v; return is; }
template <typename T> ostream &operator<<(ostream &os, const vector<T> &vec) { os << '['; for (auto v : vec) os << v << ','; os << ']'; return os; }
template <typename T, size_t sz> ostream &operator<<(ostream &os, const array<T, sz> &arr) { os << '['; for (auto v : arr) os << v << ','; os << ']'; return os; }
#if __cplusplus >= 201703L
template <typename... T> istream &operator>>(istream &is, tuple<T...> &tpl) { std::apply([&is](auto &&... args) { ((is >> args), ...);}, tpl); return is; }
template <typename... T> ostream &operator<<(ostream &os, const tuple<T...> &tpl) { os << '('; std::apply([&os](auto &&... args) { ((os << args << ','), ...);}, tpl); return os << ')'; }
#endif
template <typename T> ostream &operator<<(ostream &os, const deque<T> &vec) { os << "deq["; for (auto v : vec) os << v << ','; os << ']'; return os; }
template <typename T> ostream &operator<<(ostream &os, const set<T> &vec) { os << '{'; for (auto v : vec) os << v << ','; os << '}'; return os; }
template <typename T, typename TH> ostream &operator<<(ostream &os, const unordered_set<T, TH> &vec) { os << '{'; for (auto v : vec) os << v << ','; os << '}'; return os; }
template <typename T> ostream &operator<<(ostream &os, const multiset<T> &vec) { os << '{'; for (auto v : vec) os << v << ','; os << '}'; return os; }
template <typename T> ostream &operator<<(ostream &os, const unordered_multiset<T> &vec) { os << '{'; for (auto v : vec) os << v << ','; os << '}'; return os; }
template <typename T1, typename T2> ostream &operator<<(ostream &os, const pair<T1, T2> &pa) { os << '(' << pa.first << ',' << pa.second << ')'; return os; }
template <typename TK, typename TV> ostream &operator<<(ostream &os, const map<TK, TV> &mp) { os << '{'; for (auto v : mp) os << v.first << "=>" << v.second << ','; os << '}'; return os; }
template <typename TK, typename TV, typename TH> ostream &operator<<(ostream &os, const unordered_map<TK, TV, TH> &mp) { os << '{'; for (auto v : mp) os << v.first << "=>" << v.second << ','; os << '}'; return os; }
#ifdef HITONANODE_LOCAL
const string COLOR_RESET = "\033[0m", BRIGHT_GREEN = "\033[1;32m", BRIGHT_RED = "\033[1;31m", BRIGHT_CYAN = "\033[1;36m", NORMAL_CROSSED = "\033[0;9;37m", RED_BACKGROUND = "\033[1;41m", NORMAL_FAINT = "\033[0;2m";
#define dbg(x) cerr << BRIGHT_CYAN << #x << COLOR_RESET << " = " << (x) << NORMAL_FAINT << " (L" << __LINE__ << ") " << __FILE__ << COLOR_RESET << endl
#define dbgif(cond, x) ((cond) ? cerr << BRIGHT_CYAN << #x << COLOR_RESET << " = " << (x) << NORMAL_FAINT << " (L" << __LINE__ << ") " << __FILE__ << COLOR_RESET << endl : cerr)
#else
#define dbg(x) (x)
#define dbgif(cond, x) 0
#endif


int N;
vector<string> states;
string tmp;
void dfs() {
    if (tmp.size() == N) {
        states.push_back(tmp);
        return;
    }
    tmp += "W";
    dfs();
    tmp.back() = 'B';
    dfs();
    tmp.back() = '.';
    dfs();
    tmp.pop_back();
}

int main() {
    cin >> N;
    dfs();
    {
        auto val = [&](const string &l) -> int {
            int ret = 0;
            REP(i, l.size()) {
                if (l[i] != '.') ret += 1 << i;
            }
            return ret;
        };
        sort(states.begin(), states.end(), [&](const string &l, const string &r) { return val(l) < val(r); });
    }
    const int D = states.size();

    map<string, int> mp;
    REP(i, states.size()) mp[states[i]] = i;

    using Dya = DyadicRational<int>;
    vector<Dya> dp(D);
    constexpr int inf = 1000;
    REP(n, D) {
        const string &str = states[n];
        Dya hi(-10000), lo(10000);
        REP(i, N) {
            if (str[i] == 'W') {
                // 先手:動かす
                if (i and str[i - 1] == '.') {
                    string tmp = str;
                    tmp[i] = '.';
                    tmp[i - 1] = 'W';
                    int nxt = mp.at(tmp);
                    chmax(hi, dp[nxt]);
                }
                // 後手:食べる
                {
                    string tmp = str;
                    tmp[i] = '.';
                    int nxt = mp.at(tmp);
                    chmin(lo, dp[nxt]);
                }
            }
            if (str[i] == 'B') {
                // 後手 動かす
                if (i and str[i - 1] == '.') {
                    string tmp = str;
                    tmp[i] = '.';
                    tmp[i - 1] = 'B';
                    int nxt = mp.at(tmp);
                    chmin(lo, dp[nxt]);
                }
                // 先手:食べる
                {
                    string tmp = str;
                    tmp[i] = '.';
                    int nxt = mp.at(tmp);
                    chmax(hi, dp[nxt]);
                }
            }
        }
        dp[n] = Dya::surreal(hi, lo);
    }
    // dbg(dp);

    vector<string> S(N);
    cin >> S;
    Dya score;
    REP(i, N) {
        string tmp;
        REP(j, N) tmp += S[j][i];
        int k = mp.at(tmp);
        score += dp[k];
    }

    if (score > 0) puts("Takahashi");
    else puts("Snuke");
}

提出情報

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

コンパイルエラー

./Main.cpp: In function ‘void dfs()’:
./Main.cpp:176:20: warning: comparison of integer expressions of different signedness: ‘std::__cxx11::basic_string<char>::size_type’ {aka ‘long unsigned int’} and ‘int’ [-Wsign-compare]
  176 |     if (tmp.size() == N) {
      |         ~~~~~~~~~~~^~~~
./Main.cpp: In function ‘int main()’:
./Main.cpp:209:19: warning: unused variable ‘inf’ [-Wunused-variable]
  209 |     constexpr int inf = 1000;
      |                   ^~~

ジャッジ結果

セット名 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 22 ms 4076 KiB
001.txt AC 19 ms 4084 KiB
002.txt AC 17 ms 4204 KiB
003.txt AC 27 ms 4124 KiB
004.txt AC 19 ms 4128 KiB
005.txt AC 23 ms 4216 KiB
006.txt AC 18 ms 4252 KiB
007.txt AC 17 ms 4200 KiB
008.txt AC 19 ms 4132 KiB
009.txt AC 18 ms 4244 KiB
010.txt AC 17 ms 4172 KiB
011.txt AC 25 ms 4248 KiB
012.txt AC 17 ms 4224 KiB
013.txt AC 20 ms 4144 KiB
014.txt AC 21 ms 4252 KiB
015.txt AC 18 ms 4244 KiB
016.txt AC 19 ms 4284 KiB
017.txt AC 18 ms 4084 KiB
018.txt AC 19 ms 4172 KiB
019.txt AC 20 ms 4176 KiB
020.txt AC 18 ms 4128 KiB
021.txt AC 18 ms 4204 KiB
022.txt AC 19 ms 4192 KiB
023.txt AC 18 ms 4200 KiB
024.txt AC 24 ms 4272 KiB
025.txt AC 18 ms 4244 KiB
026.txt AC 17 ms 4284 KiB
027.txt AC 20 ms 4140 KiB
028.txt AC 2 ms 3656 KiB
029.txt AC 2 ms 3628 KiB
030.txt AC 2 ms 3508 KiB
031.txt AC 2 ms 3632 KiB
032.txt AC 3 ms 3664 KiB
033.txt AC 20 ms 4248 KiB
034.txt AC 2 ms 3532 KiB
035.txt AC 2 ms 3632 KiB
036.txt AC 7 ms 3784 KiB
037.txt AC 7 ms 3912 KiB
038.txt AC 2 ms 3532 KiB
039.txt AC 2 ms 3556 KiB
040.txt AC 24 ms 4272 KiB
041.txt AC 17 ms 4232 KiB
042.txt AC 2 ms 3644 KiB
043.txt AC 3 ms 3556 KiB
044.txt AC 3 ms 3636 KiB
045.txt AC 2 ms 3640 KiB
046.txt AC 5 ms 3596 KiB
047.txt AC 3 ms 3592 KiB
048.txt AC 2 ms 3624 KiB
049.txt AC 2 ms 3500 KiB
050.txt AC 2 ms 3668 KiB
051.txt AC 2 ms 3608 KiB
052.txt AC 5 ms 3604 KiB
053.txt AC 4 ms 3728 KiB
054.txt AC 4 ms 3764 KiB
055.txt AC 7 ms 3764 KiB
056.txt AC 7 ms 3868 KiB
057.txt AC 8 ms 3908 KiB
058.txt AC 8 ms 3788 KiB
059.txt AC 7 ms 3804 KiB
060.txt AC 7 ms 3936 KiB
061.txt AC 8 ms 3944 KiB
062.txt AC 21 ms 4248 KiB
063.txt AC 17 ms 4248 KiB
064.txt AC 17 ms 4244 KiB
065.txt AC 18 ms 4268 KiB
066.txt AC 16 ms 4288 KiB
067.txt AC 18 ms 4204 KiB
068.txt AC 2 ms 3532 KiB
069.txt AC 2 ms 3604 KiB
070.txt AC 2 ms 3588 KiB
071.txt AC 2 ms 3508 KiB
072.txt AC 2 ms 3644 KiB
073.txt AC 2 ms 3600 KiB
074.txt AC 3 ms 3620 KiB
075.txt AC 2 ms 3544 KiB
076.txt AC 2 ms 3696 KiB
077.txt AC 2 ms 3612 KiB
078.txt AC 2 ms 3556 KiB
079.txt AC 4 ms 3608 KiB
080.txt AC 4 ms 3680 KiB
081.txt AC 6 ms 3728 KiB
082.txt AC 5 ms 3672 KiB
083.txt AC 4 ms 3620 KiB
084.txt AC 4 ms 3760 KiB
085.txt AC 4 ms 3732 KiB
086.txt AC 8 ms 3944 KiB
087.txt AC 8 ms 3788 KiB
088.txt AC 8 ms 3788 KiB
089.txt AC 9 ms 3784 KiB
090.txt AC 10 ms 3908 KiB
091.txt AC 7 ms 3948 KiB
092.txt AC 9 ms 3868 KiB
093.txt AC 11 ms 3868 KiB
094.txt AC 9 ms 3856 KiB
095.txt AC 9 ms 3884 KiB
096.txt AC 18 ms 4248 KiB
097.txt AC 17 ms 4244 KiB
098.txt AC 17 ms 4256 KiB
099.txt AC 19 ms 4128 KiB
100.txt AC 21 ms 4220 KiB
101.txt AC 18 ms 4140 KiB
102.txt AC 24 ms 4200 KiB
103.txt AC 18 ms 4280 KiB
104.txt AC 18 ms 4200 KiB
105.txt AC 18 ms 4196 KiB
example0.txt AC 2 ms 3532 KiB
example1.txt AC 2 ms 3588 KiB
example2.txt AC 2 ms 3540 KiB