問題
コード
Javaで解いてみました。
import java.util.*;
public class Main {
public static final char FREE = '*';
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int nN = sc.nextInt();
int nK = sc.nextInt();
int nM = sc.nextInt();
// 単語セットの生成
HashSet<String> hsWords = new HashSet<String>();
for (int i = 0; i < nK; i++) {
String s = sc.next();
hsWords.add(s);
}
// 初期設定
int nTurn = 1; // 手番
char cFirstChar = FREE; // 頭の文字
int nRestPlayer = nN; // 残り人数 (問題文より、0になることはない)
boolean[] bRestPlayers = new boolean[nN+1];
for (int i = 1; i <= nN; i++) {
bRestPlayers[i] = true; // 残っている
}
// ゲーム開始
for (int i = 0; i < nM; i++) {
boolean bClear = false;
String s = sc.next();
if (hsWords.contains(s)) { // 発言した単語が、集合に存在し、かつ未使用であるか?
hsWords.remove(s); // 使用済みのため集合から消去
char cFirst = getFirstChar(s);
if ((cFirstChar == FREE) || (cFirstChar == cFirst)) {
char cLast = getLastChar(s);
if (cLast != 'z') {
// clear!
bClear = true;
cFirstChar = cLast;
}
}
}
if (!bClear) { // クリアできなかった場合
// プレイヤー脱落
bRestPlayers[nTurn] = false;
nRestPlayer--;
cFirstChar = FREE;
}
// 手番を次のプレイヤーにする
while(nRestPlayer > 0) {
nTurn++;
if (nTurn > nN) { nTurn = 1; }
if (bRestPlayers[nTurn]) { // 手番のプレイヤーが残っていたら、ループ終了
break;
}
}
}
// 結果出力
System.out.println(nRestPlayer); // 残り人数
for (int i = 1; i <= nN; i++) {
if (bRestPlayers[i]) {
System.out.println(i); // 残ったプレイヤーの番号
}
}
}
private static char getFirstChar(String s) {
return s.charAt(0);
}
private static char getLastChar(String s) {
return s.charAt(s.length() - 1);
}
}
解説
標準入力からの数値の読み取り
Scanner インスタンスを作り、nextInt()メソッドで数値を取得しています。
単語セットの作成
HashSet<String> インスタンスを作り、標準入力から next() メソッドで取得した文字列を格納しています。
初期設定
- 手番を1番のプレイヤーに設定
- 最初の文字をFREE(指定なし)に設定
- 残りプレイヤー人数をnN人に設定
- 残りプレイヤーの状況を表す配列を作り、true(残っている)で初期化
ゲーム開始
発言した文字列 s を取得します。
ルール1〜4のチェック
s が単語セットに含まれているか?
- ルール1) 「発言は、単語リストにある K 個の単語のうちのいずれかの単語でなければならない。」
- ルール3) 「今までに発言された単語を発言してはならない。」
を満たすかのチェックです。なお、この時点で「発言された単語」になるので単語セットから削除します。
s の最初の文字のチェック
- ルール2) 「最初の人以外の発言の頭文字は、直前の人の発言の最後の文字と一緒でなければならない。」
を満たすかのチェックです。ただし、最初の人、および、脱落した人の次の手番の人は、指定なし(FREE)となります。
s の最後の文字のチェック
- ルール4) 「z で終わる単語を発言してはならない。」
を満たすかのチェックです。
チェックを一通りクリアできたか?
クリアした場合
何もしません。(次の処理へ。)
クリアできなかった場合
プレイヤーの脱落処理を行います。
次の手番に移動
nTurn をインクリメント(nNを超えたら1に戻る)していき、脱落していないプレイヤーに当たったら、その人の手番にします。
(なお、問題文より、残りプレイヤーが1人以上いることは保証されています。)
結果の出力
- 残りプレイヤーの人数を表示
- 残りプレイヤーの番号を全て表示