0
0

解いてみた。「Bランク:みんなでしりとり」

Posted at

問題

「Bランク:みんなでしりとり」

コード

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人以上いることは保証されています。)

結果の出力

  •  残りプレイヤーの人数を表示
  •  残りプレイヤーの番号を全て表示
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