1
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?

座標系での向きの変わる移動

Posted at

今回は paiza の「座標系での向きの変わる移動」の問題に挑戦!


🧩 問題概要

  • スタート位置 (X, Y) と移動回数 N が与えられる
  • 続く N 行に L / R が順に与えられる
    • L = 現在向いている方向から 左向いて1マス進む
    • R = 現在向いている方向から 右向いて1マス進む
  • 開始時の向きは 北
  • 座標系の向きにも注意
    • 右が x 正
    • 下が y 正
  • 各移動後の座標を毎回出力する



入力例:

-18 45 6
L
L
R
R
L
R

出力例:

-19 45
-19 46
-20 46
-20 45
-21 45
-21 44






✅ OK例:

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

const lines = [];

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

rl.on('close', () => {
    const [X, Y, N] = lines[0].split(' ').map(Number);
    const d = lines.slice(1);
    
    let x = X;
    let y = Y;
    let dir = 'N';
    
    for (let i = 0; i < N; i++) {
        if (dir === 'N') {
            if (d[i] === 'L') {
                x--;
                dir = 'W'
            } else { // d[i] === 'R'
                x++;
                dir = 'E';
            }
        }
        else if (dir === 'S') {
            if (d[i] === 'L') {
                x++;
                dir = 'E'
            } else { 
                x--;
                dir = 'W';
            }
        } else if (dir === 'E') {
            if (d[i] === 'L') {
                y--;
                dir = 'N'
            } else { 
                y++;
                dir = 'S';
            }
        } else { // dir === 'W'
            if (d[i] === 'L') {
                y++;
                dir = 'S'
            } else { 
                y--;
                dir = 'N';
            }
        }
        
        console.log(x, y);
    }
});

🔍 コードの流れ

  • 1 行目から開始座標 (X, Y) と移動回数 N を読み取る
  • 移動方向の配列 d に 2 行目以降の文字列(L/R)を格納
  • 初期位置 x, y を設定し、向き dir を北(N)に設定
  • N 回ループし、以下を行う
    • 現在の向き dir と入力 d[i] により
      • 向きを更新
      • x または y を ±1 移動
    • 移動後の x, y を出力
  • 全移動が終わったら終了






✅ OK例 2:

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

const lines = [];
rl.on('line', line => lines.push(line));
rl.on('close', () => {
    const [X, Y, N] = lines[0].split(' ').map(Number);
    const moves = lines.slice(1);

    // 方角: 0=北,1=東,2=南,3=西
    let dir = 0;
    let x = X;
    let y = Y;

    // dx,dy 表
    const dx = [0, 1, 0, -1];
    const dy = [-1, 0, 1, 0]; // 下が正なので北は y-1

    for (let i = 0; i < N; i++) {
        if (moves[i] === 'R') dir = (dir + 1) % 4;
        else dir = (dir + 3) % 4; // L は -1 と同じ

        x += dx[dir];
        y += dy[dir];

        console.log(x, y);
    }
});

🔍 コードの流れ

  • 1 行目から開始座標 (X, Y) と移動回数 N を取得
  • 移動方向を moves に格納
  • 方向を数値 dir で管理(0=北, 1=東, 2=南, 3=西
  • 移動ベクトル dx, dy を定義
  • N 回ループし、以下を実行
    • 移動指示が Rdir = (dir + 1) % 4
    • 移動指示が Ldir = (dir + 3) % 4
    • x += dx[dir]
    • y += dy[dir] で座標更新
    • 更新後の x, y を出力
  • 全移動終了






🗒️ まとめ

  • 方向は毎回変わる → 移動前の向きが重要
  • 向きに応じて L/R の進む方向が変わる
     例)北向きだと L=西, R=東
  • 向きの管理方法は2種類ある
    • 文字列(N,E,S,W)で分岐
    • 数値(0~3)+ dx/dy 配列で計算
  • 数値化すると、方向操作が簡単
    • R+1
    • L-1(+3 と同じ)
      dir = (dir + 1) % 4 / dir = (dir + 3) % 4
  • dx / dy 配列により、座標更新が1行でできる
  • 毎回、移動後の座標を出力すること




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

1
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
1
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?