今回は paiza の「神経衰弱」の問題に挑戦!
これまでの準備問題で学んだことを活かして解いていく!
🃏 問題概要
テーマ
- 神経衰弱(トランプゲーム)のシミュレーション
初期状態
- トランプは 縦
H
× 横W
枚で配置される(数字のみ書かれたカード) - 同じ数字は 必ず2枚または4枚存在
- プレイヤーは
N
人、順番は 1 → 2 → … → N → 1 → …
ゲームルール
- 1番のプレイヤーから順番に進行
- 任意の2枚をめくる
- 数字が違えば → 次のプレイヤーに交代
- 数字が同じなら → その2枚を取り除いて自分のものにする(続けて同じプレイヤーの手番)
- 全てのカードがなくなったら終了
入力
- 1行目:
H W N
- 次に H行: トランプの配置(数字)
- 次に 1行: 記録の長さ
L
- 次に L行:
a b A B
(めくった2枚の位置)
出力
- 各プレイヤーが獲得したカードの枚数を 1行ずつ出力
入力例:
2 2 2
1 2
2 1
4
1 1 2 1
1 1 1 2
1 1 2 2
1 2 2 1
出力例:
4
0
✅ OK例:
const rl = require('readline').createInterface({ input:process.stdin });
const lines = [];
rl.on('line', (input) => lines.push(input));
rl.on('close', () => {
const [H, W, N] = lines[0].split(' ').map(Number);
const cardsGrid = lines.slice(1, H+1).map(line => line.split(' ').map(Number));
const L = Number(lines[H+1]);
const logs = lines.slice(H+2).map(line => line.split(' ').map(Number));
const players = Array(N).fill(0);
let currentPlayer = 0;
for (let i = 0; i < L; i++) {
const [a, b, A, B] = logs[i].map(l => l - 1); // 0-indexedに変換
if (cardsGrid[a][b] === false || cardsGrid[A][B] === false) continue;
if (cardsGrid[a][b] === cardsGrid[A][B]) {
players[currentPlayer] += 2;
cardsGrid[a][b] = false;
cardsGrid[A][B] = false;
} else {
currentPlayer = (currentPlayer + 1) % N;
}
}
players.forEach(p => console.log(p));
});
入力の読み込み
-
H
,W
,N
を取得 -
cardsGrid
にトランプの配置を格納(2次元配列) -
L
= 記録の長さを取得 -
logs
に捲られたカードの履歴を格納
プレイヤー管理用の配列
-
players = Array(N).fill(0)
→ 各プレイヤーの獲得枚数を0
で初期化
ゲームシミュレーション開始
-
currentPlayer = 0
(1番目のプレイヤーから開始) -
for (i = 0; i < L; i++)
でログを順番に処理
各ターンの処理
- ログ
[a, b, A, B]
を 0-indexed に変換 - もしカードが既に取り除かれていたら
continue
(スキップ) - もし数字が一致したら:
-
players[currentPlayer] += 2
(カード2枚獲得)
盤面から取り除く →cardsGrid[a][b] = false
などで管理
-
- 数字が違ったら:
- 次のプレイヤーへ →
currentPlayer = (currentPlayer + 1) % N
- 次のプレイヤーへ →
結果出力
- 各プレイヤーの獲得枚数を 1行ずつ出力
🗒️ まとめ
- 配列の扱い
- トランプ配置は 2次元配列 で保持
- 取り除かれたカードは
false
など特殊な値で管理
- プレイヤーの順番管理
-
currentPlayer
を持つ - 不一致なら
(currentPlayer + 1) % N
で交代 - 一致ならそのまま同じプレイヤーが継続
-
- 獲得枚数の記録
-
players = Array(N).fill(0)
で初期化
一致したらplayers[currentPlayer] += 2
-
- ログ処理の注意点
- 入力は 1-indexed → プログラムでは 0-indexed に直す必要あり
- 既に取り除かれたカードを選んだ場合はスキップする処理を入れる
- 出力
- 最終的に
players.forEach(p => console.log(p))
で人数分の結果を出力
- 最終的に