問題
コード
Javaで解いてみました。
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int nN = sc.nextInt();
int nM = sc.nextInt();
String sS = sc.next();
// 相手の出す手の種類の集計
int nGu = 0;
int nChoki = 0;
int nPa = 0;
for (int i = 0; i < nN; i++) {
switch(sS.charAt(i)) {
case 'G':
nGu++;
break;
case 'C':
nChoki++;
break;
case 'P':
nPa++;
break;
default:
// NOP
break;
}
}
// こちらの出す手の種類と勝利数を求める
int nMaxPa = nM / 5;
int nMaxWin = 0;
for (int mPa = nMaxPa; mPa >= 0; mPa--) {
int nRest = nM - mPa*5;
if (nRest % 2 != 0) {
continue;
}
int mChoki = nRest / 2;
int mGu = nN - (mChoki + mPa);
if (mGu < 0) {
continue;
}
// 勝利数を求め、最大勝利数を更新する
int nWin = Math.min(mGu, nChoki) + Math.min(mChoki, nPa) + Math.min(mPa, nGu);
if (nMaxWin < nWin) {
nMaxWin = nWin;
}
}
// 結果出力
System.out.println(nMaxWin);
}
}
解説
標準入力からの数値と文字列の読み取り
Scanner インスタンスを作り、nextInt()メソッドで数値(ジャンケンの回数$n$、指の本数の合計$m$)を、next()メソッドで文字列を取得しています。
相手の出す手の種類の集計
手の順番によらず、種類の合計のみが必要なので、文字列を検索し、
- 相手がグーを出した回数:$G$
- 相手がチョキを出した回数:$C$
- 相手がパーを出した回数:$P$
を求めます。
こちらの出せる手の種類(回数)を求める
最大で出せるパーの回数を求める
最大で出せるパーの回数($q$)は指の数の合計($m$)をパーの指の数($5$)で整数除算した時の値になります。
パーを出す回数をループさせる
パーを出す回数($p$)を $0$ 〜 $q$ 回までループさせます。
チョキの回数を求める
チョキの回数($c$)を求めます。指の数の合計($m$)は、グーの回数を$g$とした時、
\begin{align}
0g + 2c + 5p &= m \\
2c &= m - 5p
\end{align}
より、$(m - 5p)$は2で割り切れる必要があります。よって、
c = \frac{m - 5p}{2}
となります。そして、グーの回数($g$)は、
g = n - (c + p)
となります。この時、$g$は0以上である必要があります。
最大勝利回数を求める
こちらがグー($g$)、相手がチョキ($C$)の時、グーでの勝利回数は $min(g,C)$となります。チョキ($c$)とパー($p$)も同様にして考えると、勝利回数($w_k$)は、
w_k = min(g,C) + min(c,P) + min(p, G)
となります。あとは、最も大きい$w_k$が答えとなります。