AOJ2119 Finding the Top RPS Player
問題リンク Finding the Top RPS Player
- 概要
N人の人を集め、じゃんけんを行う。
N人は最初0勝である。ゲームは1ターンに同時に任意の数だけ試合が行われる。ただし、試合は連勝数の等しい人同士のみ行う事が出来る。k連勝同士の人が試合をすると勝った方がk+1連勝となり、負けた人は0勝に戻る。
M連勝する人が現れるための最小ターン数を答えよ。
2 <= N <= 20
1 <= M < N
- 解法
貪欲のようなシミュレートで解きました。
勝数が大きい人を1ターン中にたくさん作り出したいため、行える試合は全て行った方が得です。
c[M]: M連勝している人の人数
という表を作りながら1ターン毎に試合結果をシミュレートしていきます。
c[ ]が現在のターンで、この配列から次のターンの状態を表すnext[ ]を埋めます。
c[k]/2の人数だけ勝つのでnext[k+1]+=c[k]/2となります。同様に、c[k]/2の人数は負けるので、next[0]+=c[k]/2となります。見落としてはいけない点として、c[k]が奇数だった場合、試合をしていない人が1人残っているので、next[k]+=1となります。
- ソース
import java.util.Arrays; import java.util.Scanner; //Finding the Top RPS Player public class AOJ2119 { void run(){ Scanner sc = new Scanner(System.in); for(int T=1;;T++){ int N = sc.nextInt(), M = sc.nextInt(); if((N|M)==0)break; int[][] c = new int[2][M+1]; c[0][0] = N; for(int x=1,t=1;;t++,x=1-x){ Arrays.fill(c[x], 0); for(int i=0;i<M;i++){ c[x][i+1]+=c[1-x][i]/2; c[x][0]+=c[1-x][i]/2; c[x][i]+=c[1-x][i]-c[1-x][i]/2*2; } if(c[x][M]!=0){ System.out.println("Case "+T+": "+t); break; } } } } public static void main(String[] args) { new AOJ2119().run(); } }