冰面棋盤遊戲:石頭從起點 S 出發,沿直線滑動直到撞到障礙(1)或出界(失敗)或到達終點 G(成功)。撞到障礙時停在障礙前一格,障礙消失,可重新選擇方向繼續。最多 10 次移動,求最少移動次數到達 G。
w h(寬、高 ≤ 20)0 0 結束int vis[25][25], w, h, sx, sy, gx, gy, minStep = 1e9;
int dx[4] = {1,0,-1,0}, dy[4] = {0,1,0,-1};
void dfs(int x, int y, int step) {
if (step >= 10 || step >= minStep) return;
for (int d = 0; d < 4; ++d) {
int nx = x + dx[d], ny = y + dy[d];
if (vis[nx][ny]) continue; // 相鄰即障礙/邊界,無法移動
// 滑動
while (!vis[nx][ny]) {
nx += dx[d]; ny += dy[d];
if (nx == gx && ny == gy) { minStep = min(minStep, step+1); return; }
if (nx < 0 || nx >= h || ny < 0 || ny >= w) break; // 出界
}
// 撞到障礙 (nx,ny) 是障礙,石頭停在 (nx-dx, ny-dy)
if (nx >= 0 && nx < h && ny >= 0 && ny < w && step+1 < 10) {
vis[nx][ny] = 0; // 移除障礙
dfs(nx-dx[d], ny-dy[d], step+1);
vis[nx][ny] = 1; // 回溯恢復
}
}
}
w h 但存儲常用 [h][w]