結果
問題 | No.611 Day of the Mountain |
ユーザー | はまやんはまやん |
提出日時 | 2017-12-18 10:15:10 |
言語 | C++14 (gcc 12.3.0 + boost 1.83.0) |
結果 |
AC
|
実行時間 | 921 ms / 2,017 ms |
コード長 | 5,418 bytes |
コンパイル時間 | 1,983 ms |
コンパイル使用メモリ | 173,108 KB |
実行使用メモリ | 415,488 KB |
最終ジャッジ日時 | 2024-05-09 11:02:36 |
合計ジャッジ時間 | 11,333 ms |
ジャッジサーバーID (参考情報) |
judge2 / judge5 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 780 ms
413,312 KB |
testcase_01 | AC | 774 ms
413,440 KB |
testcase_02 | AC | 731 ms
413,568 KB |
testcase_03 | AC | 921 ms
413,440 KB |
testcase_04 | AC | 531 ms
413,696 KB |
testcase_05 | AC | 526 ms
413,696 KB |
testcase_06 | AC | 534 ms
415,488 KB |
testcase_07 | AC | 540 ms
415,232 KB |
testcase_08 | AC | 517 ms
413,312 KB |
testcase_09 | AC | 519 ms
413,184 KB |
testcase_10 | AC | 526 ms
413,440 KB |
testcase_11 | AC | 517 ms
413,312 KB |
ソースコード
#include<bits/stdc++.h> #define rep(i,a,b) for(int i=a;i<b;i++) #define rrep(i,a,b) for(int i=a;i>=b;i--) #define fore(i,a) for(auto &i:a) #pragma GCC optimize ("-O3") using namespace std; void _main(); int main() { cin.tie(0); ios::sync_with_stdio(false); _main(); } //--------------------------------------------------------------------------------------------------- template<int MOD> struct ModInt { static const int Mod = MOD; unsigned x; ModInt() : x(0) { } ModInt(signed sig) { x = sig < 0 ? sig % MOD + MOD : sig % MOD; } ModInt(signed long long sig) { x = sig < 0 ? sig % MOD + MOD : sig % MOD; } int get() const { return (int)x; } ModInt &operator+=(ModInt that) { if ((x += that.x) >= MOD) x -= MOD; return *this; } ModInt &operator-=(ModInt that) { if ((x += MOD - that.x) >= MOD) x -= MOD; return *this; } ModInt &operator*=(ModInt that) { x = (unsigned long long)x * that.x % MOD; return *this; } ModInt &operator/=(ModInt that) { return *this *= that.inverse(); } ModInt operator+(ModInt that) const { return ModInt(*this) += that; } ModInt operator-(ModInt that) const { return ModInt(*this) -= that; } ModInt operator*(ModInt that) const { return ModInt(*this) *= that; } ModInt operator/(ModInt that) const { return ModInt(*this) /= that; } ModInt inverse() const { long long a = x, b = MOD, u = 1, v = 0; while (b) { long long t = a / b; a -= t * b; std::swap(a, b); u -= t * v; std::swap(u, v); } return ModInt(u); } bool operator==(ModInt that) const { return x == that.x; } bool operator!=(ModInt that) const { return x != that.x; } ModInt operator-() const { ModInt t; t.x = x == 0 ? 0 : Mod - x; return t; } }; template<int MOD> ostream& operator<<(ostream& st, const ModInt<MOD> a) { st << a.get(); return st; }; template<int MOD> ModInt<MOD> operator^(ModInt<MOD> a, unsigned long long k) { ModInt<MOD> r = 1; while (k) { if (k & 1) r *= a; a *= a; k >>= 1; } return r; } typedef ModInt<201712111> mint; string to_binary(int N, int digit = -1) { string s = ""; int ok = 0; rrep(i, 30, 0) { int m = 1 << i; if (N < m) { if(ok)s += "0"; }else s += "1", N -= m, ok = 1;} if (0 < digit and s.size() < digit) {int n = digit - s.size();rep(i, 0, n) s = "0" + s;} return s;} /*--------------------------------------------------------------------------------------------------- ∧_∧ ∧_∧ (´<_` ) Welcome to My Coding Space! ( ´_ゝ`) / ⌒i / \ | | / / ̄ ̄ ̄ ̄/ | __(__ニつ/ _/ .| .|____ \/____/ (u ⊃ ---------------------------------------------------------------------------------------------------*/ #define INF INT_MAX/2 int H, W; string A[1010]; int B[1010][1010]; int dp[1010][1010]; mint dp2[400][1 << 18]; //--------------------------------------------------------------------------------------------------- void _main() { cin >> H >> W; rep(y, 0, H) cin >> A[y]; if (W <= H) { rep(y, 0, H) rep(x, 0, W) if (A[y][x] != '?') B[y][x] = A[y][x] - '0'; } else { rep(y, 0, H) rep(x, 0, W) if (A[y][x] != '?') B[x][y] = A[y][x] - '0'; swap(W, H); } rep(y, 0, H) rep(x, 0, W) dp[y][x] = INF; if (A[0][0] == '?') dp[0][0] = 1; else dp[0][0] = B[0][0]; rep(y, 0, H) rep(x, 0, W) { if (B[y + 1][x] == 0) dp[y + 1][x] = min(dp[y + 1][x], dp[y][x] + 1); else dp[y + 1][x] = min(dp[y + 1][x], dp[y][x] + B[y + 1][x]); if (B[y][x + 1] == 0) dp[y][x + 1] = min(dp[y][x + 1], dp[y][x] + 1); else dp[y][x + 1] = min(dp[y][x + 1], dp[y][x] + B[y][x + 1]); } int T = dp[H - 1][W - 1]; printf("%d\n", T); dp2[0][0] = 1; rep(y, 0, H) rep(x, 0, W) rep(msk, 0, 1 << W) { int id = y * W + x; int upok = 0; if (y) { if(msk & (1 << x)) upok = 1; if (B[y][x] == 0) { if (dp[y - 1][x] + 1 != dp[y][x]) upok = 0; } else { if (dp[y - 1][x] + B[y][x] != dp[y][x]) upok = 0; } } else { if(x == 0) upok = 1; } int leok = 0; if (x) { if (msk & (1 << (x - 1))) leok = 1; if (B[y][x] == 0) { if (dp[y][x - 1] + 1 != dp[y][x]) leok = 0; } else { if (dp[y][x - 1] + B[y][x] != dp[y][x]) leok = 0; } } if (upok or leok) { int nmsk = msk | (1 << x); dp2[id + 1][nmsk] += dp2[id][msk]; } if (!upok and !leok) { int nmsk = msk & (~(1 << x)); if (B[y][x] == 0) dp2[id + 1][nmsk] += dp2[id][msk] * 9; else dp2[id + 1][nmsk] += dp2[id][msk]; } else { if (B[y][x] == 0) { int nmsk = msk & (~(1 << x)); dp2[id + 1][nmsk] += dp2[id][msk] * 8; } } } //rep(y, 0, H) rep(x, 0, W) rep(msk, 0, 1 << W) if(dp2[y * W + x][msk].get()) printf("dp2[%d][%d][%s] = %d\n", y, x, to_binary(msk, W).c_str(), dp2[y * W + x][msk].get()); mint ans = 0; rep(msk, 0, 1 << W) if (msk & (1 << (W - 1))) ans += dp2[H * W][msk]; printf("%d\n", ans.get()); }