一般的なアイデア
1から9までのK枚のカードがあり、それぞれが5枚のカードに分けられます。
スコアリングルールは次のとおりです。∑ i = 1 9i×10 ci \ displaystyle \ sum_(i = 1)^ 9 i \ times 10 ^(c_i)i = 1∑9私××1 0c私,其中 C i C_i C私この人は免許を持っていますかiiiのシート数。
各人が4枚のカードを配ったら、最初の人に勝つ確率を尋ねます。
問題解決のアイデア
③∑ i = 1 9i ×10 ci \ displaystyle \ sum_ {i = 1} ^ 9 i \ times 10 ^ {c_i}i = 1∑9私××1 0c私あなたがすべてを理解していれば言うのは簡単です。
この文の意味は、4つの2がある場合、2 * 10000(4 0s)ポイントが付与されるということです。1 3、3 * 10(1 0)ポイントを取得します。5枚が0枚の場合、5 * 1(0 0)ポイントを獲得できます。
一人一人のカードの状況を列挙し、全体の状況に対する勝ちの状況の割合を計算することができます。
一人称の最後の写真は1、二人称の最後の写真は2、合計9件、
一人称の最後の写真は5、二人称の最後の写真は6、合計18ケース;
…… (純粋に架空の)
一人称1-9、二人称1-9、合計81回を列挙する必要があります。
2枚の山に3枚、1枚のカードが9枚残っている場合、1人目が2枚、2人目が1枚になるとすると、1人目は合計A 3 1 = 3 A ^ {1} _3になります。 = 3A31=3つのケースでは、2人目の人の合計はA 9 1 = 9 A ^ {1} _ 9 = 9です。A91=9ケース、合計3 ∗ 9 = 27 3 * 9 = 273∗9=2つの7の状況。
デッキに91が残っている場合、最初の人が1を取得し、2番目の人も1を取得することを考慮すると、合計A 9 2 = 72 A ^ {2} _9 = 72A92=7 2例でした。
いずれにせよ、全体の状況は次のとおりです。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;
}