山傘のプログラミング勉強日記

プログラミングに関する日記とどうでもよい雑記からなるブログです。

[yukicoder] No.161 制限ジャンケン

問題

No.161 制限ジャンケン - yukicoder

カイジの限定じゃんけんのような設定ですね。

自分と相手の手札は全てわかっている状況下で、相手が次に何を出すかもわかっています。

考え方

カイジの設定のようにじゃんけんを手札を使ってすることとします。

自分の手札は、グー、チョキ、パーそれぞれ、 G,  C,  P 枚あります。

同様に相手の手札の枚数をそれぞれ、 g,  c,  p とします。

このとき、自分が勝つ最大の数 m_1は、

 m_1 = \min (G, c) + \min (C, p) + \min (P, g)

となります。

次に、あいこの数を計算します。上の計算から、残りの手札を使ってあいことなる数の最大値 m_2を考えます。自分の手札と相手の手札の残りの枚数をそれぞれ、 G_1,  C_1,  P_1 g_1,  c_1,  p_1 とします。これらを用いて、

 m_2 = \min(G_1, g_1) + \min(C_1, c_1) + \min(P_1, p_1)

となります。

よって解答は、

 3m_1 + m_2

となります。

また、残りの手札を計算するときは、

 G_1 = G - \min (G, c),  c_1 = c - \min (G, c)

のように計算できます。

コード

import java.util.Scanner;

public class Exec0161 {
    public static void main(String[] args) {
        Scanner scan = new Scanner(System.in);
        int G = scan.nextInt();
        int C = scan.nextInt();
        int P = scan.nextInt();
        String S = scan.next();
        scan.close();
        // 相手の各手の数
        int cnt1 = 0;
        int cnt2 = 0;
        int cnt3 = 0;
        for(int i = 0; i < S.length(); i++) {
            char c = S.charAt(i);
            if(c == 'G') {
                cnt1++;
            }else if(c == 'C') {
                cnt2++;
            }else {
                cnt3++;
            }
        }
        //System.out.println(cnt1 +" " + cnt2 + " "+ cnt3);
        // 勝つパターン
        int m1 = Math.min(G, cnt2);
        int m2 = Math.min(C, cnt3);
        int m3 = Math.min(P, cnt1);

        int p3 = m1 + m2 + m3;

        G -= m1; cnt2 -= m1;
        C -= m2; cnt3 -= m2;
        P -= m3; cnt1 -= m3;

        // あいこ
        m1 = Math.min(G, cnt1);
        m2 = Math.min(C, cnt2);
        m3 = Math.min(P, cnt3);

        int p2 =  m1 + m2 + m3;
        int ans = 3 * p3 + p2;

        System.out.println(ans);
    }
}