結果
問題 | No.611 Day of the Mountain |
ユーザー |
![]() |
提出日時 | 2017-12-18 10:15:10 |
言語 | C++14 (gcc 13.3.0 + boost 1.87.0) |
結果 |
AC
|
実行時間 | 780 ms / 2,017 ms |
コード長 | 5,418 bytes |
コンパイル時間 | 2,237 ms |
コンパイル使用メモリ | 174,124 KB |
実行使用メモリ | 415,416 KB |
最終ジャッジ日時 | 2024-12-15 23:22:23 |
合計ジャッジ時間 | 9,279 ms |
ジャッジサーバーID (参考情報) |
judge5 / judge3 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 3 |
other | AC * 9 |
ソースコード
#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/2int 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());}