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 の「ひとりすごろく」の問題に挑戦!


問題概要

ゲーム設定

  • 一直線上に並んだ N 個のマスがある
  • 各マスには 1〜6 の数字が書かれている

サイコロ

  • 通常と異なる配置の 特殊な6面サイコロ
  • 面には ID が固定で割り当てられている:T, B, U, D, L, R
  • 入力で「各 ID に対応する数字」が与えられる
  • 裏表:
T ↔ B
U ↔ D
L ↔ R

初期状態

  • スタート地点にサイコロを置く
  • T 面が上
  • U 面がゴール方向

移動ルール

  • 次のマスに進むとき:
    • 上面の数字が次のマスの数字になるようにサイコロを回転させる
  • 回転は 90° 単位
    • 奥 / 手前 / 左 / 右
    • 必要なら 複数回 回転してよい

目的

  • スタートからゴールまで進む
  • 必要な回転回数の最小値を求める



入力例:

1 6 2 5 4 3
4
1
5
3
4

出力例:

4






✅OK例:

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

const lines = [];

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

rl.on('close', () => {
    const num = lines[0].split(' ').map(Number);
    const N = Number(lines[1]);
    const p = lines.slice(2).map(Number);
    
    let count = 0; // 回転数
    let topIdx = 0; // 上面のインデックス
    
    for (let i = 0; i < N; i++) {
        // 次のマス
        const nextIdx = num.indexOf(p[i]);
        
        // 反対の面
        let opposite;
        if (topIdx % 2 !== 0) {
            opposite = topIdx - 1;
        } else {
            opposite = topIdx + 1;
        }
        
        if (topIdx === nextIdx) {
            // 回転なし
        } else if (nextIdx === opposite) {
            // 反対は2回転
            count += 2;
        } else {
            // それ以外は1回転
            count++;
        }
        
        topIdx = nextIdx; // 上面を更新
    }
    
    // 結果を出力
    console.log(count);
});

🔍コードの流れ

  • 入力を受け取る
    • サイコロの面配置 num = [T, B, U, D, L, R]
    • マスの数 N
    • 各マスに書かれた数字配列 p
  • 初期状態を設定
    • 回転回数 count = 0
    • サイコロの上面は T(index 0)とする
  • スタートからゴールまで順に処理
    • 各マス i について次を行う:
      • そのマスに必要な数字 p[i]
      • サイコロのどの面(index)かを indexOf で調べる
      • 現在の上面 topIdx の 裏面の index を求める
        • 偶数なら +1
        • 奇数なら -1
      • 回転回数を判定する
        • 同じ面 → 0 回転
        • 裏面 → 2 回転
        • それ以外 → 1 回転
      • 上面を次のマスの面に更新する
  • 合計回転数を出力






📝まとめ

観察ポイント

  • 各マスで重要なのは:
    • 今の上面
    • 次に必要な数字(=次の上面)
  • 向き(U/D/L/R)を完全に追跡する必要はない

サイコロの性質

  • 上面が決まれば、裏面は一意に決まる
  • 6 面の関係は 固定ペア
0 ↔ 1
2 ↔ 3
4 ↔ 5

各ステップでの最小回転数

状態 必要回転
今の上面 = 次の面 0 回
次の面 = 裏面 2 回
それ以外 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?