山東大學程式設計思維19級每月練習(一)組合數學做法
飛飛很喜歡打牌,他決定苦練牌技,終成賭神!
飛飛有 A?×?B 張撲克牌,每張撲克牌有一個大小(整數,記為a,范圍區間是 0 到 A?-?1)和一個花色(整數,記為b,范圍區間是 0 到 B?-?1,
撲克牌是互異的,也就是獨一無二的,也就是說沒有兩張牌大小和花色都相同,
“一手牌”的意思是你手里有5張不同的牌,這 5 張牌沒有誰在前誰在后的順序之分,它們可以形成一個牌型, 我們定義了 9 種牌型,如下是 9 種牌型的規則,我們用“低序號優先”來匹配牌型,即這“一手牌”從上到下滿足的第一個牌型規則就是它的“牌型編號”(一個整數,屬于1到9) :
- 同花順: 同時滿足規則 5 和規則 4.
- 炸彈 : 5張牌其中有4張牌的大小相等.
- 三帶二 : 5張牌其中有3張牌的大小相等,且另外2張牌的大小也相等.
- 同花 : 5張牌都是相同花色的.
- 順子 : 5張牌的大小形如 x, x?+?1, x?+?2, x?+?3, x?+?4
- 三條: 5張牌其中有3張牌的大小相等.
- 兩對: 5張牌其中有2張牌的大小相等,且另外3張牌中2張牌的大小相等.
- 一對: 5張牌其中有2張牌的大小相等.
- 要不起: 這手牌不滿足上述的牌型中任意一個.
現在, 飛飛從 A?×?B 張撲克牌中拿走了 2 張牌!分別是 (a1, b1) 和 (a2,?b2). (其中a表示大小,b表示花色)
現在要從剩下的撲克牌中再隨機拿出 3 張!組成一手牌!!
其實飛飛現在要預言他的未來的可能性,即他將拿到的“一手牌”的可能性,我們用一個 “牌型編號(一個整數,屬于1到9)” 來表示這手牌的牌型,那么他的未來有 9 種可能,但每種可能的方案數不一樣,
現在飛飛想要計算一下 9 種牌型中,每種牌型的方案數,
Input
第 1 行包含了整數 A 和 B (5?≤?A?≤?25,?1?≤?B?≤?4).
第 2 行包含了整數 a1, b1, a2, b2 (0?≤?a1,?a2?≤?A?-?1,?0?≤?b1,?b2?≤?B?-?1,?(a1,?b1)?≠?(a2,?b2)).
Output
輸出一行,這行有 9 個整數,每個整數代表了 9 種牌型的方案數(按牌型編號從小到大的順序)
Case 1
Input
5 2
1 0 3 1
Output
0 0 0 0 8 0 12 36 0
Case 2
Input
25 4
0 0 24 3
Output
0 2 18 0 0 644 1656 36432 113344
助教在發布實驗20個小時后增加規則:
不可以使用組合數學公式!!!
奈何已經用組合數學做完
正確的做法應該是列舉
先把之前做的發出來
思路有時間再寫
推導實在是太麻煩了
PS:博主最后使用暴力迭代求解,實驗結束前就不發布了,有其
他想法的歡迎私聊交流
//by sdudyl
#include<iostream>
#include<string>
using namespace std;
long long int res[10] = { 0 };
int main()
{
int A, B;
cin >> A >> B;
int a1, b1, a2, b2;
cin >> a1 >> b1 >> a2 >> b2;
int tag;
if (a1 > a2)
tag = a1 - a2;
else
tag = a2 - a1;
//①同花順
if (b1 != b2 || A < 5 || tag>4 || a1 == a2)
res[1] = 0;
else if (tag > 4 || tag == 0 || A < 5)
res[1] = 0;
else if (tag == 4)
res[1] = 1;
else if (tag == 3)
if (a1 == 0 || a2 == 0 || a1 == A - 1 || a2 == A - 1)
res[1] = 1;
else
res[1] = 2;
else if (tag == 2)
if (a1 == 0 || a2 == 0 || a1 == A - 1 || a2 == A - 1)
res[1] = 1;
else if (A == 5)
res[1] = 1;
else if (A == 6)
res[1] = 2;
else if (a1 == 1 || a2 == 1 || a1 == A - 2 || a2 == A - 2)
res[1] = 2;
else
res[1] = 3;
else if (tag == 1)
if (a1 == 0 || a2 == 0 || a1 == A - 1 || a2 == A - 1)
res[1] = 1;
else if (A == 5)
res[1] = 1;
else if (A == 6)
res[1] = 2;
else if (A == 7)
if (a1 == 1 || a2 == 1 || a1 == A - 2 || a2 == A - 2)
res[1] = 2;
else
res[1] = 3;
else
if (a1 == 1 || a2 == 1 || a1 == A - 2 || a2 == A - 2)
res[1] = 2;
else if (a1 == 2 || a2 == 2 || a1 == A - 3 || a2 == A - 3)
res[1] = 3;
else
res[1] = 4;
//②炸彈(4張一樣)√
if (B < 4)
res[2] = 0;
else
if (a1 == a2)
res[2] = (B - 2)*(B - 3)*(A*B - 4) / 2;
else//a1不等于a2
{
//a1是炸彈 a2不是
res[2] += (B - 1)*(B - 2)*(B - 3) / 6;
//a2是炸彈 a1不是
res[2] += (B - 1)*(B - 2)*(B - 3) / 6;
}
//③三帶二 √
if (B < 3)
res[3] = 0;
else
if (a1 == a2)
{
//a1和a2是一對二
res[3] += (A - 1)*B*(B - 1)*(B - 2) / 6;
//a1和a2是一對三
res[3] += (B - 2)*B*(B - 1) / 2 * (A - 1);
}
else//a1和a2不等
{
//a1是對子,a2是三子
res[3] += (B - 1)*(B - 1)*(B - 2) / 2;
//a1是三子,a2是對子
res[3] += (B - 1)*(B - 1)*(B - 2) / 2;
}
//④同花
if (b1 != b2 || (b1 == b2 && A < 5))
res[4] = 0;
else
res[4] = (A - 2)*(A - 3)*(A - 4) / 6;
if (res[4] != 0 && res[1] != 0)
res[4] = res[4] - res[1];
//⑤順子(不能是同花順!)
if (tag > 4 || tag == 0 || A < 5)
res[5] = 0;
else if (tag == 4)
res[5] = B * B*B;
else if (tag == 3)
if (a1 == 0 || a2 == 0 || a1 == A - 1 || a2 == A - 1)
res[5] = B * B*B;
else
res[5] = 2 * B*B*B;
else if (tag == 2)
if (a1 == 0 || a2 == 0 || a1 == A - 1 || a2 == A - 1)
res[5] = B * B*B;
else if (A == 5)
res[5] = B * B*B;
else if (A == 6)
res[5] = 2 * B*B*B;
else if (a1 == 1 || a2 == 1 || a1 == A - 2 || a2 == A - 2)
res[5] = 2 * B*B*B;
else
res[5] = 3 * B*B*B;
else if (tag == 1)
if (a1 == 0 || a2 == 0 || a1 == A - 1 || a2 == A - 1)
res[5] = B * B*B;
else if (A == 5)
res[5] = B * B*B;
else if (A == 6)
res[5] = 2 * B*B*B;
else if (A == 7)
if (a1 == 1 || a2 == 1 || a1 == A - 2 || a2 == A - 2)
res[5] = 2 * B*B*B;
else
res[5] = 3 * B*B*B;
else
if (a1 == 1 || a2 == 1 || a1 == A - 2 || a2 == A - 2)
res[5] = 2 * B*B*B;
else if (a1 == 2 || a2 == 2 || a1 == A - 3 || a2 == A - 3)
res[5] = 3 * B*B*B;
else
res[5] = 4 * B*B*B;
if (res[5] != 0 && res[1] != 0)
res[5] = res[5] - res[1];
//⑥三條 √
if (B < 3)
res[6] = 0;
else
{
if (a1 == a2)
{
//a1和a1相等但不是三條
res[6] += (A - 1)*B*(B - 1)*(B - 2) / 6;
//a1和a2是三條,另外兩張不一樣也不等于a1
res[6] += (B - 2)*B*B*(A - 1)*(A - 2) / 2;
}
else//a1不等于a2
{
//a1和a2都不是三條
res[6] += (A - 2)*B * (B - 1)*(B - 2) / 6;
//a1是三條,a2不是,還有一張不等于a2、a1的
res[6] += (B - 1)*(B - 2)*(A - 2)*B / 2;
//a2是三條,a1不是;
res[6] += (B - 1)*(B - 2)*(A - 2)*B / 2;
}
}
//⑦兩對 √
if (B < 2)
res[7] = 0;
else
if (a1 == a2)
res[7] = (A - 1)*B*(B - 1)*(A - 2)*B / 2;
else//a1不等于a2
{
//a1和a2都是對子
res[7] += (B - 1)*(B - 1)*(A - 2)*B;
//a1是對子,a2不是對子
res[7] += (B - 1)*(A - 2)*B*(B - 1) / 2;
//a1不是對子,a2是對子
res[7] += (B - 1)*(A - 2)*B*(B - 1) / 2;
}
//⑧一對 √
if (B < 2)
res[8] = 0;
else
if (a1 == a2)
res[8] = (A - 1)*(A - 2)*(A - 3) / 6 * B*B*B;
else//a1不等于a2
{
//a1和a2都不是對子
res[8] += (A - 2)*B*(B - 1)*(A - 3)*B / 2;
//a1是對子,a2不是
res[8] += (B - 1)*(A - 2)*(A - 3)*B*B / 2;
//a2是對子,a1不是
res[8] += (B - 1)*(A - 2)*(A - 3)*B*B / 2;
}
//⑨要不起 √
res[9] = (A*B - 2)*(A*B - 3)*(A*B - 4) / 6 - res[1] - res[2] - res[3] - res[4] - res[5] - res[6] - res[7] - res[8];
for (int i = 1; i <= 9; i++)
cout << res[i] << " ";
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/267470.html
標籤:AI
上一篇:Graphviz正確插入姿勢
