結果
| 問題 |
No.1759 Silver Tour
|
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2021-11-18 19:00:33 |
| 言語 | C++17(gcc12) (gcc 12.3.0 + boost 1.87.0) |
| 結果 |
AC
|
| 実行時間 | 1,687 ms / 2,000 ms |
| コード長 | 3,486 bytes |
| コンパイル時間 | 5,408 ms |
| コンパイル使用メモリ | 141,880 KB |
| 最終ジャッジ日時 | 2025-01-25 19:20:34 |
|
ジャッジサーバーID (参考情報) |
judge1 / judge4 |
| 純コード判定しない問題か言語 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 4 |
| other | AC * 40 |
ソースコード
#include <array>
#include <cassert>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <utility>
#include <vector>
using namespace std;
#include "atcoder/modint.hpp"
using mint = atcoder::dynamic_modint<-1>;
#define rep(i, n) for (int i = 0; i < (n); i++)
int dh[] = {1, 1, -1, -1, -1};
int dw[] = {1, -1, 1, 0, -1};
int main() {
int H, W, mod;
cin >> H >> W >> mod;
mint::set_mod(mod);
if (H % 2 != 0) {
int ans = W == 1 ? 1 : 0;
std::cout << ans << "\n";
exit(0);
}
using Board = array<array<bool, 64>, 2>;
Board init;
rep(i, 2) rep(j, 64) init[i][j] = 0;
Board fin;
rep(i, 2) rep(j, 64) fin[i][j] = 0;
rep(i, 2) rep(j, W) fin[i][j] = 1;
using Data = pair<Board, pair<int, int>>;
auto ok = [&](Data& d) {
auto& board = d.first;
int i = 0;
while (i != W) {
int s = board[0][i] + board[1][i];
if (s == 1) break;
i++;
}
while (i != W) {
int s = board[0][i] + board[1][i];
if (s != 1) break;
i++;
}
while (i != W) {
int s = board[0][i] + board[1][i];
if (s == 1) break;
i++;
}
return i == W;
};
set<Data> valid;
{
queue<Data> Q;
rep(i, W) {
Data start{fin, make_pair(0, i)};
valid.insert(start);
Q.emplace(start);
}
while (!Q.empty()) {
Data data = Q.front();
Q.pop();
auto& board = data.first;
auto& [h, w] = data.second;
assert(board[h][w] == 1);
board[h][w] = 0;
rep(k, 5) {
int nh = h - dh[k];
int nw = w - dw[k];
if (!(0 <= nh and nh < 2 and 0 <= nw and nw < W)) continue;
if (board[nh][nw] == 0) continue;
Data nxt{data};
nxt.second = make_pair(nh, nw);
if (!ok(nxt)) continue;
if (valid.count(nxt)) continue;
valid.insert(nxt);
Q.emplace(nxt);
}
}
}
// cerr << valid.size() << "\n";
mint ans = 0;
vector<mint> dp(W);
rep(iter, H / 2) {
if (iter == 0) {
fill(begin(dp), end(dp), mint{1});
} else {
vector<mint> dp2{dp};
rep(i, W) {
if (i) dp2[i - 1] += dp[i];
if (i != W - 1) dp2[i + 1] += dp[i];
}
swap(dp, dp2);
}
map<Data, mint> mp;
queue<Data> Q;
vector<mint> nx(W);
rep(i, W) {
Data start{init, make_pair(1, i)};
start.first[1][i] = 1;
if(!valid.count(start)) continue;
mp[start] = dp[i];
Q.emplace(start);
}
while (!Q.empty()) {
Data data = Q.front();
Q.pop();
auto& board = data.first;
auto& [h, w] = data.second;
mint curval = mp[data];
//ans += curval;
if (board == fin) {
assert(h == 0);
nx[w] = curval;
continue;
}
rep(k, 5) {
int nh = h + dh[k];
int nw = w + dw[k];
if (!(0 <= nh and nh < 2 and 0 <= nw and nw < W)) continue;
if (board[nh][nw] == 1) continue;
Data nxt{data};
nxt.first[nh][nw] = 1;
nxt.second = make_pair(nh, nw);
if (valid.count(nxt) == 0) continue;
if (mp.count(nxt)) {
mp[nxt] += curval;
continue;
}
mp[nxt] = curval;
Q.emplace(nxt);
}
}
/*
for (auto& [k, v] : mp) {
cerr << "dump:" << k.second.first << " " << k.second.second << " "
<< v.val() << "\n";
}
*/
swap(dp, nx);
}
for(auto&x : dp) ans += x;
std::cout << ans.val() << "\n";
}