目錄
- 題目大意
- 解題思路
- AC代碼
題目大意
有1~9的牌各K張,每人分5張,
得分規則是 ∑ i = 1 9 i × 1 0 c i \displaystyle \sum_{i=1}^9 i \times 10^{c_i} i=1∑9?i×10ci?,其中 C i C_i Ci?是這個人有牌 i i i的張數,
當每人發了4張牌時,問第一個人獲勝的概率,
解題思路
把 ∑ i = 1 9 i × 1 0 c i \displaystyle \sum_{i=1}^9 i \times 10^{c_i} i=1∑9?i×10ci?理解了一切就好說了,
這句話的意思是假如有4張2,那么就獲得2 * 10000(4個0)分,1張3,獲得3 * 10(1個0)分,0張5,就獲得5 * 1(0個0)分,
我們可以把每個人獲得牌的情況列舉,計算獲勝的情況占總情況的比例,
第一個人最后一張是1,第二個人最后一張是2,共9種情況;
第一個人最后一張是5,第二個人最后一張是6,共18種情況;
… …(純屬虛構)
需列舉第一個人1 ~ 9,第二個人1 ~ 9,共81次,
假如有牌堆里還剩下3張2,9張1,考慮第一個人得到2,第二個人得到1時,第一個人共有 A 3 1 = 3 A^{1}_3=3 A31?=3種情況,第二個人共有 A 9 1 = 9 A^{1}_9=9 A91?=9種情況,一共有 3 ? 9 = 27 3*9=27 3?9=27種情況,
假如有牌堆里還剩下9張1,考慮第一個人得到1,第二個人也得到1時,一共有 A 9 2 = 72 A^{2}_9=72 A92?=72種情況,
而不管怎樣,總情況就是 A 剩 余 張 數 2 A^{2}_{剩余張數} A剩余張數2?,
AC代碼
#include <bits/stdc++.h>
using namespace std;
#define mem(a) memset(a, 0, sizeof(a))
#define dbg(x) cout << #x << " = " << x << endl
#define fi(i, l, r) for (int i = l; i < r; i++)
#define cd(a) scanf("%d", &a)
typedef long long ll;
ll getScore(ll s[]) //計算總得分
{
ll ans=0;
for(ll i=1;i<10;i++)
{
ans+=i*pow(10,s[i]);
}
return ans;
}
int main()
{
ll k;
cin >> k;
char s[10], t[10];
cin >> s >> t;
ll shengyu[10] = {0}; //shengyu[i]表示i還剩多少張
for (ll i = 1; i < 10; i++)
shengyu[i] = k; //沒有發牌時1~9都各剩k張
ll suma[10] = {0}; //s中有每種牌各多少
ll sumb[10] = {0}; //t中有每種牌各多少
for (ll i = 0; i < 4; i++) //已經發下來的前4張
{
shengyu[s[i] - '0']--; //第一個人起到了s[i],s[i]的剩余張數減1
shengyu[t[i] - '0']--; //第一個人起到了t[i],t[i]的剩余張數減1
suma[s[i]-'0']++;//第一個人起到了s[i],第一個人的s[i]的張數加1
sumb[t[i]-'0']++;//第一個人起到了t[i],第一個人的t[i]的張數加1
}
ll canWin=0; //所有可以獲勝的情況
for (ll i = 1; i <= 9; i++) //第一個人起到了i
{
for (ll j = 1; j <= 9; j++) //第二個人起到了j
{
bool sfbx=false; //這種情況是否不行(當剩余牌沒有i和j時,這種情況不行)
if(shengyu[i]<=0)sfbx=true; //沒i了
if(shengyu[j]<=0)sfbx=true; //沒j了
if(i==j && shengyu[i]<=1)sfbx=true; //沒有兩張i
suma[i]++; //第一個人起到了i
sumb[j]++; //第二個人起到了j
if(!sfbx) //不是不行
{
ll sa=getScore(suma); //第一個人的得分
ll sb=getScore(sumb); //第二個人的得分
if(sa>sb) //第一個人獲勝
{
if(i==j) //兩人最后一張牌相同
canWin += shengyu[i] * (shengyu[i]- 1);
else
canWin += shengyu[i] * shengyu[j];
}
}
suma[i]--; //這種情況考慮結束,放回最后一張牌
sumb[j]--;
}
}
ll shengyuAll = k*9-8; //所有剩余的牌
ll canAll = shengyuAll*(shengyuAll-1); //所有可能的情況(對應A shengyuAll 2)
double ans = 1. * canWin / canAll;
printf("%.15lf\n", ans);
return 0;
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/264750.html
標籤:其他
