結果
| 問題 |
No.2928 Gridpath
|
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2024-10-12 16:56:53 |
| 言語 | D (dmd 2.109.1) |
| 結果 |
TLE
|
| 実行時間 | - |
| コード長 | 2,513 bytes |
| コンパイル時間 | 5,689 ms |
| コンパイル使用メモリ | 173,312 KB |
| 実行使用メモリ | 5,248 KB |
| 最終ジャッジ日時 | 2024-10-12 16:57:40 |
| 合計ジャッジ時間 | 17,950 ms |
|
ジャッジサーバーID (参考情報) |
judge5 / judge4 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 2 TLE * 1 |
| other | AC * 19 TLE * 1 |
ソースコード
import std;
void main () {
// 逆を考える。
// 任意の移動経路について、パスになってさえいればそれが最短になるような配置が存在するかもしれない。
// パス列挙はできる。無駄なパスをどう検出するかが悩みどころ。->できそう?
int H, W; readln.read(H, W);
auto S = () {
int i, j; readln.read(i, j);
i--, j--;
return tuple(i, j);
}();
auto G = () {
int i, j; readln.read(i, j);
i--, j--;
return tuple(i, j);
}();
bool is_in (int y, int x) {
return 0 <= y && y < H && 0 <= x && x < W;
}
const auto dxy = [
[-1, 0],
[1, 0],
[0, 1],
[0, -1],
];
int ans = 0;
auto vis = new bool[][](H, W);
void dfs (int y, int x) {
if (G[0] == y && G[1] == x) {
// 4マス固まっていたらダメ?
bool ok = true;
foreach (i; 0..H) {
foreach (j; 0..W) {
if (!vis[i][j]) continue;
int c = 0;
foreach (d; dxy) {
int ni = i + d[0], nj = j + d[1];
if (is_in(ni, nj) && vis[ni][nj]) c++;
}
if (3 <= c) ok = false;
}
}
// スタート、ゴールに触れてるのに無視したらダメ?
int gc = 0;
foreach (d; dxy) {
int ny = G[0] + d[0], nx = G[1] + d[1];
if (is_in(ny, nx) && vis[ny][nx]) gc++;
}
int sc = 0;
foreach (d; dxy) {
int ny = S[0] + d[0], nx = S[1] + d[1];
if (is_in(ny, nx) && vis[ny][nx]) sc++;
}
if (2 <= gc || 2 <= sc) {
ok = false;
}
if (ok) {
ans++;
}
return;
}
foreach (d; dxy) {
int ny = y + d[0], nx = x + d[1];
if (is_in(ny, nx) && !vis[ny][nx]) {
vis[ny][nx] = true;
dfs(ny, nx);
vis[ny][nx] = false;
}
}
}
vis[S[0]][S[1]] = true;
dfs(S[0], S[1]);
writeln(ans);
}
void read (T...) (string S, ref T args) {
import std.conv : to;
import std.array : split;
auto buf = S.split;
foreach (i, ref arg; args) {
arg = buf[i].to!(typeof(arg));
}
}