愚直シミュレーション問題!
問題概要
A さん、B さん、C さんの 3 人が以下のようなカードゲームをプレイしています。
最初、3 人はそれぞれ 'a', 'b', 'c' いずれかの文字が書かれたカードを、何枚か持っている。これらは入力で与えられた順番に持っており、途中で並べ替えたりしない。
A さんのターンから始まる。現在自分のターンである人がカードを 1 枚以上持っているならば、そのうち先頭のカードを捨てる。その後、捨てられたカードに書かれているアルファベットと同じ名前の人のターンとなる。
現在自分のターンである人がカードを 1 枚も持っていないならば、その人がゲームの勝者となり、ゲームは終了する。
3 人が最初に持っているカードを表す文字列 が与えられる。各文字列の 番目の文字が、上から 枚目のカードの書かれたアルファベットを表す。最終的に誰がこのゲームの勝者となるかを求めよ。
制約
考えたこと
プレイヤーの手持ちのカードが先頭から捨てられていく様子をシミュレーションするときの手法として、添字を進めていくという方法が典型的だ。
たとえば、文字列 "acac" に対して、先頭にあるカードを表す添字 iter
を用意する。まだ 1 枚も捨てられていないとき、iter = 0
とする。
先頭のカードを捨てたとき、文字列を "acac" の先頭の文字を消して "cac" とする代わりに、iter
を 1 増やして iter = 1
とするのだ。そうすることで、文字列を直接変更することなく「先頭のカードを捨てた」ことを表現できる。
今回の問題では、3 つの文字列のそれぞれについて、添字 iter[0]
, iter[1]
, iter[2]
を用意してシミュレーションすればよい。下のコードのように実装できる。
コード
#include <bits/stdc++.h> using namespace std; int main() { vector<string> S(3); for (int i = 0; i < 3; i++) cin >> S[i]; // 現在 player が誰か、各プレイヤーのカードがどこまで進んでいるか int player = 0; vector<int> iter(3, 0); // カードがなくなった人が指定されるまで while (iter[player] < S[player].size()) { char next_player = S[player][iter[player]]; iter[player]++; // player のカードを進める if (next_player == 'a') player = 0; else if (next_player == 'b') player = 1; else player = 2; } cout << (char)('A' + player) << endl; }