0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

今回は paiza の「リバーシの操作(斜め)」の問題に挑戦!


問題概要

  • H 行、横 W 列の盤面が与えられる
  • 盤面には
    • '*':すでに置かれている自分の石
    • '.':何も置かれていないマス
      が存在する
  • 指定されたマス (Y, X) は必ず '.' であり、ここに 新しく石を 1 つ置く

操作ルール(斜め方向のはさみ)

  • 石を (Y, X) に置いたあと、
  • 斜め 4 方向(右上・右下・左下・左上)をそれぞれ調べる
  • ある方向について、
    '*' → '.' → '.' → … → '*'
    のように
    斜め方向で両端が '*' ではさまれている場合、
    その間の '.' をすべて '*' にする
  • 途中で
    • 盤面の外に出る
    • '*' に到達できない
      場合は、その方向は何もしない
  • 新たに置いた石によってさらに置ける場合があっても操作は 1 回で終了(連鎖処理なし)

操作後の盤面を 上から順に H 行出力 する



入力例:

3 3 0 0
..*
...
*.*

出力例:

*.*
.*.
*.*






✅OK例:

const rl = require('readline').createInterface({ input: process.stdin });

const lines = [];

rl.on('line', (line) => lines.push(line));

rl.on('close', () => {
    const [H, W, Y, X] = lines[0].split(' ').map(Number);
    const grid = lines.slice(1).map(row => row.split(''));
    
    const directionList = [[-1, 1], [1, 1], [1, -1], [-1, -1]];
    grid[Y][X] = '*';
    
    for (const direction of directionList) {
        const [dy, dx] = direction;
        let ny = Y + dy;
        let nx = X + dx;
        
        const path = [];
        
        while (0 <= ny && ny < H && 0 <= nx && nx < W) {
            if (grid[ny][nx] === '*') {
                for (const [py, px] of path) {
                    grid[py][px] = '*';
                }
                break;
            }
            path.push([ny, nx]);
            ny += dy;
            nx += dx;
        }
    }
    
    grid.forEach(g => console.log(g.join('')));
});

🔍 コードの流れ

  • 標準入力を1行ずつ読み込み、配列 lines に保存する
  • 入力1行目から
    • 盤面の高さ H
    • W
    • 石を置く座標 Y, X
      を取得する
  • 続く H 行を読み取り、2次元配列 grid として盤面を作成する
  • 斜め4方向(右上・右下・左下・左上)を (dy, dx) の配列 directionList として定義する
  • 指定されたマス (Y, X) に石 '*' を置く
  • 各斜め方向について次の処理を行う
    • (Y, X) の1マス先から探索を開始する
    • 通過したマスを path に順番に記録する
    • 進んだ先で '*' が見つかったら
      • path に記録したマスをすべて '*' にする(はさみ成立)
    • 盤面の外に出た場合は、その方向は何もしない
  • すべての方向の処理が終わったら更新後の盤面を1行ずつ出力する






📝まとめ

  • Step2(縦横)と ロジックはほぼ同じ
    違いは「方向が斜め」なだけ
  • 斜め方向は (dy, dx) で表現できる
    • (-1, 1):右上
    • (1, 1):右下
    • (1, -1):左下
    • (-1, -1):左上
  • 処理の流れ(1方向あたり)
    • (Y, X) の1マス先から探索開始
    • 通過したマスを path に保存
    • '*' に到達したら
      path 内のマスをすべて '*' にする
    • 盤面外に出たら
      → その方向は何もしない
  • 最初に (Y, X)'*' にしてから探索する




僕の失敗談(´;ω;`)と解決法🐈

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?