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?

ポスターの貼り付け作業

Posted at

今回は paiza の「ポスターの貼り付け作業」の問題に挑戦!


🧩 問題概要

  • 池の周りに N 本の木 があり、木は時計回りに 1〜N 番 で番号が付いている。
  • 最初に 木 A にポスターを貼り付ける。
  • その後は次のルールに従って、すべての木にポスターを貼る順番を求める。

🔹 貼り付けルール

  • 方向 S"CW" なら時計回り、"CCW" なら反時計回りに進む。
  • ポスターを貼っていない木だけを数えて、B 本目の木に次のポスターを貼る。
  • すべての木にポスターを貼るまでこれを繰り返す。
  • 途中で同じ木に戻ってきても、「貼っていない木」だけをカウントする

🔹 入出力形式

入力

N   ← 木の本数
A   ← 最初に貼る木の番号(1始まり)
S   ← "CW" or "CCW"(進行方向)
B   ← 数える間隔(B 本目に貼る)

出力

ポスターを貼った順番(半角スペース区切り)



入力例:

5
2
CW
3

出力例:

2 5 4 1 3






✅OK例:

// readline モジュールを使って標準入力を受け取る準備
const rl = require('readline').createInterface({ input: process.stdin });

// 入力行を格納する配列
const lines = [];

// 入力を1行ずつ配列に追加
rl.on('line', (input) => lines.push(input));

// 入力終了後に処理を実行
rl.on('close', () => {
    // 入力データの読み取り
    const N = Number(lines[0]);   // 木の本数
    const A = Number(lines[1]);   // 最初にポスターを貼る木の番号(1始まり)
    const S = lines[2];           // 進行方向("CW" or "CCW")
    const B = Number(lines[3]);   // 進む間隔

    // 木の番号リスト(0からN-1までの配列)
    let trees = Array.from({ length: N }, (_, i) => i);

    // 貼った順番を格納する配列
    const ans = [];

    // 現在位置(配列のインデックス)※0始まりに調整
    let cur = A - 1;

    // 全ての木にポスターを貼るまで繰り返す
    while (trees.length > 0) {
        // 現在の木にポスターを貼る(出力用に+1して元の番号に戻す)
        ans.push(trees[cur] + 1);

        // 現在の木を削除(もう貼らない)
        trees.splice(cur, 1);

        // 全て貼り終えたら終了
        if (trees.length === 0) break;

        // 次の位置を計算
        if (S === 'CW') {
            // 時計回り:B-1本進む
            cur = (cur + B - 1) % trees.length;
        } else if (S === 'CCW') {
            // 反時計回り:B本戻る(負の値防止に+trees.length)
            cur = (cur - B + trees.length) % trees.length;
        }

        // 念のため負インデックス補正(範囲を0〜length-1に保つ)
        cur = (cur + trees.length) % trees.length;
    }

    // 結果をスペース区切りで出力
    console.log(ans.join(' '));
});

🧭 コードの流れ

  1. 入力準備
    • readline モジュールで標準入力(コンソール入力)を受け取る準備をする。
    • 入力された各行を lines 配列に保存。
  2. 入力終了後の処理 (rl.on('close', ...))
    • 入力内容をそれぞれの変数に変換して使いやすくする。
      • N: 木の本数
      • A: 最初にポスターを貼る木(1始まり)
      • S: 進行方向(CW: 時計回り / CCW: 反時計回り)
      • B: 進む間隔(B本目の木に貼る)
  3. 木のリストを作成
    • trees = [0, 1, 2, ..., N-1]
      → まだポスターを貼っていない木の番号を管理するための配列。
  4. 現在位置を設定
    • cur = A - 1
      → 入力が1始まりなので、配列インデックス(0始まり)に合わせて調整。
  5. 繰り返し処理開始
    • trees 配列が空になるまで繰り返す。
  6. 現在の木にポスターを貼る
    • ans.push(trees[cur] + 1)
      → 木の番号を出力用に1始まりに戻して保存。
    • trees.splice(cur, 1)
      → 貼った木をリストから削除(もう選ばれない)。
  7. 全て貼り終えたら終了
    • if (trees.length === 0) break;
  8. 次に貼る木を決定
    • 時計回り(CW)の場合:
      cur = (cur + B - 1) % trees.length
      現在の木を除外して、右方向に B 本進む。
    • 反時計回り(CCW)の場合:
      cur = (cur - B + trees.length) % trees.length
      左方向に B 本戻る(負のインデックス防止で補正)。
  9. 負インデックスの補正
    • cur = (cur + trees.length) % trees.length
      → 配列の範囲外にならないように調整。
  10. 結果出力
    • 全ての木に貼った順番を console.log(ans.join(' ')) で表示。






📝 学習のまとめ

考え方:

「貼っていない木」だけが残るリストから、
現在位置を基準にB本目を数えて削除していくシミュレーション。


🪄 ポイント:

  • 配列の削除 (splice) → 貼り終えた木をリストから除外。
  • インデックスの補正 (% trees.length) → 配列の端を超えたらループ。
  • 方向ごとに移動式が異なる
    • 時計回り:+B-1
    • 反時計回り:-B
  • 常に「貼っていない木」だけをカウントするのがキーポイント。




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

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?