今回は paiza の「1マスの陣取り2」の問題に挑戦!
問題概要
-
H×Wの盤面が与えられる。 - 盤面には以下の3種類のマスがある:
-
'*'… プレイヤーの現在の陣地(必ず1つ) -
'.'… 通れるマス -
'#'… 障害物(通れない)
-
- プレイヤーは 現在位置(
'*')の上下左右のマス に 1 マス移動できる。 - 移動できるマス(上下左右の 4 マス)が 障害物でなければ, そのマスをプレイヤーの陣地
'*'に変える。 - 変換後の盤面を出力する。
入力例:
6 6
......
...#..
..#*#.
......
......
......
出力例:
......
...#..
..#*#.
...*..
......
......
✅OK例:
const rl = require('readline').createInterface({ input: process.stdin });
const lines = [];
rl.on('line', (input) => lines.push(input));
rl.on('close', () => {
const [H, W] = lines[0].split(' ').map(Number);
const gridS = lines.slice(1).map(line => line.split(''));
for (let i = 0; i < H; i++) {
for (let j = 0; j < W; j++) {
if (gridS[i][j] === '*') {
if (i > 0 && gridS[i-1][j] !== '#') gridS[i-1][j] = '*';
if (i < H-1 && gridS[i+1][j] !== '#') gridS[i+1][j] = '*';
if (j > 0 && gridS[i][j-1] !== '#') gridS[i][j-1] = '*';
if (j < W-1 && gridS[i][j+1] !== '#') gridS[i][j+1] = '*';
gridS.forEach(s => console.log(s.join('')));
return;
}
}
}
});
🔍 コードの流れ
- 入力を読み込み、
linesに貯める。 - 1 行目から
H, Wを数値で取得する。 - 続く
H行を 2 次元配列gridSに分解して格納。 - 全マスを 2 重ループで走査し、
'*'の位置を探す。 -
'*'を見つけたら、その上下左右をチェックする。- 盤面の範囲内で、かつ
'#'でないなら上書きで'*'にする。
- 盤面の範囲内で、かつ
- 盤面全体を出力する。
-
returnで処理終了('*'は 1 つなので)。
📝まとめ
- 位置を見つけるには盤面を 二重ループ で走査する。
- 上下左右の4方向は、
境界チェック(範囲内か) と 障害物チェック('#'ではないか) が必須。 - 条件を満たしたマスを
'*'に書き換えるだけ。 - 前回のコードに障害物の判定を追加するだけ。