今回は 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))で人数分の結果を出力
 
- 最終的に 
