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) に置いたあと、
  • 縦・横・斜めの 8 方向 をそれぞれ調べる
  • ある方向について
    • '*' → '.' → '.' → … → '*'
      のように
      両端が '*' ではさまれている場合、その間の '.' をすべて '*' にする
  • 途中で
    • 盤面の外に出る
    • '*' に到達できない
      場合は、その方向は何もしない
  • 新たに置いた石によってさらに石が置ける場合があっても操作は 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(''));
    
    // 8方向
    const directionList = [
        [-1, 0], // 上
        [-1, 1], // 右上
        [0, 1],  // 右
        [1, 1],  // 右下
        [1, 0],  // 下 
        [1, -1], // 左下
        [0, -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('')));
});

🔍 コード全体の流れ

  • 入力をすべて lines 配列に読み込む
  • 1行目から
    • 盤面サイズ H, W
    • 石を置く座標 (Y, X)
      を取得する
  • 続く H 行から盤面を grid(2次元配列)として作成する

石を置いて挟む処理

  • 縦・横・斜めの 8方向 を配列で用意する
  • 指定されたマス (Y, X) に石 '*' を置く
  • 8方向それぞれについて以下を行う
    • その方向に 1マス先 から探索を開始する
    • 進んだマスを path に順番に保存する
    • 盤面の外に出るまで繰り返す
      • '*' にぶつかったら
        → はさめたと判断し、path にあるマスをすべて '*' にする
        → その方向の探索を終了
      • '*' でなければ
        → そのマスを path に追加して次へ進む

出力

  • すべての方向の処理が終わった後の盤面を各行ごとに文字列として出力する






📝まとめ

  • Step5 は Step2(縦横)+ Step4(斜め) の統合版
  • すべての方向は (dy, dx) の配列で管理できる
    • 上・下・左・右
    • 右上・右下・左下・左上
  • 実装パターンは全方向共通
    • 1マス先から探索開始
    • 通過マスを path に一時保存
    • '*' に到達したら
      path をまとめて '*' にする




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

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?