kmjp's blog

競技プログラミング参加記です

yukicoder : No.1220 yukipoker

最近yukicoderの問題増加ペースがすごいな。
https://yukicoder.me/problems/no/1220

問題

Mスート、番号1~Nの合計カードNM毎において、K枚選んだ時、フラッシュとストレートで発生しにくいのはどちらか。

解法

フラッシュとなるのは \displaystyle C(N,K) \times M通り。
ストレートとなるのは、スートを無視すると番号の取り方は(N-K+1)通りなので、スートを考慮すると \displaystyle M^K \times (N-K+1)通り。

これらの大小を取ることを考える。
そのままだと大きな値となるので、両者対数を取って比較しよう。
1~10^5の階乗の対数値を事前に取っておくとよい。

int Q;
int N,M,K;

double lfact[1010101];

void solve() {
	int i,j,k,l,r,x,y; string s;
	
	
	for(i=2;i<=101000;i++) lfact[i]=lfact[i-1]+log(i);
	
	cin>>Q;
	while(Q--) {
		cin>>N>>M>>K;
		
		double F=0,S=0;
		F=lfact[N]-lfact[K]-lfact[N-K]+log(M);
		S=K*log(M)+log(N-K+1);
		
		if(F<S) cout<<"Flush"<<endl;
		else cout<<"Straight"<<endl;
		
	}
}

まとめ

実際これN,M,Kがどれぐらいになるとストレートが優位になるんだろ。