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?

裏返せる可能性(斜め)

Last updated at Posted at 2025-12-18

今回は paiza の「裏返せる可能性(斜め)」の問題に挑戦!


問題概要

  • H 行、横 W 列の盤面
  • 指定されたマス (Y, X) に 石を 1 つ置く
  • 盤面の各マスは次のルールで文字を決める

ルール

  • 石を置いたマス (Y, X)'!'
  • (Y, X) を通る 斜め方向(4方向) にあるすべてのマス → '*'
  • 上記以外のマス → '.'

座標について

  • 左上が (0, 0)
  • 下方向が y の正
  • 右方向が x の正

条件に従って作成した盤面を 上から順に H 行出力 する



入力例:

3 3 0 0  // H W Y X

出力例:

!..
.*.
..*






✅OK例:

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

const lines = [];

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

rl.on('close', () => {
    const [H, W, Y, X] = lines[0].split(' ').map(Number);
    
    const grid = Array.from({ length: H }, () => Array(W).fill('.'));
    grid[Y][X] = '!';
    
    const direction = [
        [-1, 1],
        [1, 1],
        [1, -1],
        [-1, -1]
    ]
    
    for (const d of direction) {
        const [dy, dx] = d;
        
        let ny = Y + dy;
        let nx = X + dx;
        
        while (0 <= ny && ny < H && 0 <= nx && nx < W) {
            grid[ny][nx] = '*';
            ny += dy;
            nx += dx;
        }
    }
    
    grid.forEach(g => console.log(g.join('')));
});

🔍 コードの流れ

  • 標準入力を1行ずつ読み込み、配列 lines に格納する
  • 入力の1行目から、盤面の高さ H、幅 W、石の座標 (Y, X) を取得する
  • すべて '.' で埋めた H × W の盤面 grid を作成する
  • 石を置くマス (Y, X)'!' をセットする
  • 斜め4方向(右上・右下・左下・左上)を表す移動量を direction に定義する
  • 各斜め方向について処理を行う
    • 現在位置を (Y, X) の1マス先に設定する
    • 盤面の範囲内にいる間、同じ方向に進み続ける
    • 通過するマスを '*' にする
  • すべての斜め方向の処理が終わったら
  • 盤面を1行ずつ文字列にして出力する






✅OK例 2:

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

const lines = [];

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

rl.on('close', () => {
    const [H, W, Y, X] = lines[0].split(' ').map(Number);
    
    const grid = Array.from({ length: H }, () => Array(W).fill('.'));
    
    for (let i = 0; i < H; i++) {
        let row = '';
        
        for (let j = 0; j < W; j++) {
            if (i === Y && j === X) {
                row += '!';
            } else if (Math.abs(i - Y) === Math.abs(j - X)) {
                row += '*';
            } else {
                row += '.';
            }
        }
        
        console.log(row);
    }
});

|i - Y| === |j - X|

が成り立つとき、
(Y, X) から見て「縦に進んだ分」と「横に進んだ分」が同じなので、
そのマスは必ず斜め方向にある。

ポイント

  • 斜め = 縦の差と横の差が同じ
  • 全方向対応 → 絶対値
  • 中心マスは別処理






📝まとめ

  • 斜め方向は 4方向 ある
  • 斜め移動は (dy, dx) の組で表せる
    • (-1, 1):右上
    • (1, 1):右下
    • (1, -1):左下
    • (-1, -1):左上
  • ある方向に対して
    • 1マスずつ同じ (dy, dx) を足しながら進む
    • 盤面の外に出るまで '*' を置き続ける
  • 中心マス (Y, X)'*' にしてはいけないため 必ず別処理で '!' にする
  • 別解として
    • 全マス走査 + 条件分岐 でも解ける
    • Math.abs(i - Y) === Math.abs(j - X)
      (Y, X) から見て斜め方向にあるマス
  • 絶対値を使うことで、4方向すべてを 1つの条件式 で表現できる
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?