POJ 2005 Blackjack
問題
トランプがnセット(1セットあたりジョーカーなしの52枚)与えられ、このカードデッキを使ってブラックジャックを行う。
この中からディーラーが1枚、あなたが2枚をランダムにピックアップし、場にお互いが見えるように置く。ディーラーがランダムにもう1枚引いたときにあなたが勝つ確率を求めよ。
やりかた
自分の得点はすぐ計算できる。その際にAを11として加算しても21より大きくならないならそうする。
ディーラーの得点は最初に引いたディーラーのカードがAか否かで場合分け。場合分けした上で各場合についてディーラーが引いた場合に負けとなるカードの総枚数(自分の勝ちパターン数)を計算し、ディーラーが引きうるカードの総数n * 52 - 3(全パターン数)で割れば割合となる。
以下ソース。
int p(char c){ if(c == 'A') return 1; else if(isdigit(c)) return (int)(c - '0'); else return 10; } int num(char c){ if(c == 'A') return 1; if(c == 'K') return 13; if(c == 'Q') return 12; if(c == 'J') return 11; if(c == 'T') return 10; return (int)(c - '0'); } int main(int argc, char **argv){ int card[14]; int n; while(cin >> n, n){ if(n == 0) break; for(int i = 1; i <= 13; i++) card[i] = 4 * n; int dealer = 0, me = 0; char a, b, c; cin >> a >> b >> c; card[num(a)]--; card[num(b)]--; card[num(c)]--; me = p(b) + p(c); if(b == 'A' || c == 'A') me = (me + 10 <= 21) ? me + 10 : me; int chance = 0; if(a == 'A'){//ディーラーは最初にAを引いた for(int i = 1; i <= 13; i++){ if(i == 1){//ディーラーは2枚目にAを引くケース dealer = 12; if(dealer < me && me <= 21) chance += card[i]; }else{//ディーラーは2枚目にA以外をを引くケース dealer = min(10, i) + 11; if(dealer > 21) dealer -= 10; if(dealer < me && me <= 21) chance += card[i]; } } printf("%.3f\%\n\n", chance * 100.0 / (n * 52 - 3)); }else{//ディーラーは最初にAではないカードを引いた for(int i = 1; i <= 13; i++){ dealer = p(a); if(i == 1){//ディーラーは2枚目にAを引くケース dealer += 11; if(dealer > 21) dealer -= 10; if(dealer < me && me <= 21) chance += card[i]; }else{//ディーラーは2枚目にA以外を引くケース dealer += min(i, 10); if((dealer > 21 && me <= 21) || (dealer < me && me <= 21)) chance += card[i]; } } printf("%.3f\%\n\n", chance * 100.0 / (n * 52 - 3)); } } return 0; }
場合分けはもう少し削れるはず。
Get up! 明日のSUPER ST@R!