Official
I - くねくね Editorial by kaage
前に動いた方向が上下か左右かと場所を持って BFS すればよいです。 頂点を倍化して辺を張る方向を変える、という考え方もあります。
#include <algorithm>
#include <iostream>
#include <queue>
#define rep(i, n) for(int i = 0; i < int(n); i++)
using P = std::pair<int, int>;
constexpr int INF = 1e9;
int H, W, sx, sy, gx, gy;
char S[2010][2010];
int dist[2010][2010][2];
int main() {
std::cin >> H >> W >> sx >> sy >> gx >> gy;
sx--;
sy--;
gx--;
gy--;
rep(i, H) rep(j, W) std::cin >> S[i][j];
std::queue<std::pair<P, bool>> que;
rep(i, H) rep(j, W) rep(k, 2) dist[i][j][k] = INF;
que.push({{sx, sy}, false});
que.push({{sx, sy}, true});
dist[sx][sy][0] = dist[sx][sy][1] = 0;
while (!que.empty()) {
auto p = que.front();
que.pop();
if (!p.second) {
auto [nx, ny] = p.first;
nx--;
if (0 <= nx && S[nx][ny] != '#' && dist[nx][ny][1] == INF) {
dist[nx][ny][1] = dist[p.first.first][p.first.second][0] + 1;
que.push({{nx, ny}, 1});
}
nx += 2;
if (nx < H && S[nx][ny] != '#' && dist[nx][ny][1] == INF) {
dist[nx][ny][1] = dist[p.first.first][p.first.second][0] + 1;
que.push({{nx, ny}, 1});
}
} else {
auto [nx, ny] = p.first;
ny--;
if (0 <= ny && S[nx][ny] != '#' && dist[nx][ny][0] == INF) {
dist[nx][ny][0] = dist[p.first.first][p.first.second][1] + 1;
que.push({{nx, ny}, 0});
}
ny += 2;
if (ny < W && S[nx][ny] != '#' && dist[nx][ny][0] == INF) {
dist[nx][ny][0] = dist[p.first.first][p.first.second][1] + 1;
que.push({{nx, ny}, 0});
}
}
}
int ans = std::min(dist[gx][gy][0], dist[gx][gy][1]);
if (ans == INF)
std::cout << -1 << std::endl;
else
std::cout << ans << std::endl;
return 0;
}
posted:
last update: