結果
| 問題 |
No.3121 Prime Dance
|
| ユーザー |
|
| 提出日時 | 2025-04-20 13:27:39 |
| 言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
WA
|
| 実行時間 | - |
| コード長 | 2,583 bytes |
| コンパイル時間 | 2,112 ms |
| コンパイル使用メモリ | 206,792 KB |
| 実行使用メモリ | 7,848 KB |
| 最終ジャッジ日時 | 2025-04-20 13:27:42 |
| 合計ジャッジ時間 | 3,057 ms |
|
ジャッジサーバーID (参考情報) |
judge5 / judge4 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 2 |
| other | AC * 7 WA * 14 |
ソースコード
#include <bits/stdc++.h>
using namespace std;
constexpr int LIM = 6000; // 素数判定上限(十分余裕)
bitset<LIM + 1> isPrime;
/* エラトステネス */
void sieve() {
isPrime.set();
isPrime[0] = isPrime[1] = 0;
for (int i = 2; i * i <= LIM; ++i)
if (isPrime[i])
for (int j = i * i; j <= LIM; j += i)
isPrime[j] = 0;
}
/* a0,b0 から最小の k>=0 を返す(両方素数になる) */
int min_loop(int a0, int b0) {
for (int k = 0; a0 + k <= LIM && b0 + k <= LIM; ++k) {
int A = a0 + k, B = b0 + k;
if (A >= 2 && B >= 2 && isPrime[A] && isPrime[B]) return k;
}
return -1; // 見つからず
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
sieve();
int H, W;
if (!(cin >> H >> W)) return 0;
int Sx, Sy, Gx, Gy;
cin >> Sx >> Sy >> Gx >> Gy;
--Sx; --Sy; --Gx; --Gy; // 0-index
vector<string> g(H);
for (auto &row : g) cin >> row;
/* -------- BFS で到達判定とループ判定 -------- */
queue<pair<int,int>> q;
vector vis(H, vector<char>(W, 0));
vis[Sx][Sy] = 1;
q.emplace(Sx, Sy);
const int dx4[4] = {1,-1,0,0};
const int dy4[4] = {0,0,1,-1};
while (!q.empty()) {
auto [x,y] = q.front(); q.pop();
for (int dir = 0; dir < 4; ++dir) {
int nx = x + dx4[dir], ny = y + dy4[dir];
if (0 <= nx && nx < H && 0 <= ny && ny < W &&
g[nx][ny] != '#' && !vis[nx][ny]) {
vis[nx][ny] = 1;
q.emplace(nx, ny);
}
}
}
if (!vis[Gx][Gy]) { // そもそも辿り着けない
cout << -1 << '\n';
return 0;
}
bool vLoop = false, hLoop = false;
for (int i = 0; i < H; ++i) for (int j = 0; j < W; ++j) if (vis[i][j]) {
if (i + 1 < H && vis[i+1][j]) vLoop = true; // 縦に 2 連
if (j + 1 < W && vis[i][j+1]) hLoop = true; // 横に 2 連
}
/* -------- 最小 k,ℓ を決定 -------- */
int dx = Gx - Sx, dy = Gy - Sy;
int A0 = max(0, dx), B0 = max(0, -dx); // 基底回数
int C0 = max(0, dy), D0 = max(0, -dy);
int k = min_loop(A0, B0);
int ell = min_loop(C0, D0);
if (k == -1 || ell == -1) { cout << -1 << '\n'; return 0; }
if (k > 0 && !vLoop) { cout << -1 << '\n'; return 0; }
if (ell> 0 && !hLoop) { cout << -1 << '\n'; return 0; }
long long ans = (A0 + B0 + C0 + D0) + 2LL * (k + ell);
cout << ans << '\n';
return 0;
}