题意:
东东有 A × B 张扑克牌。每张扑克牌有一个大小(整数,记为a,范围区间是 0 到 A - 1)和一个花色(整数,记为b,范围区间是 0 到 B - 1。
扑克牌是互异的,也就是独一无二的,也就是说没有两张牌大小和花色都相同。
“一手牌”的意思是你手里有5张不同的牌,这 5 张牌没有谁在前谁在后的顺序之分,它们可以形成一个牌型。 我们定义了 9 种牌型,如下是 9 种牌型的规则,我们用“低序号优先”来匹配牌型,即这“一手牌”从上到下满足的第一个牌型规则就是它的“牌型编号”(一个整数,属于1到9):
同花顺: 同时满足规则 2 和规则 3.
顺子 : 5张牌的大小形如 x, x + 1, x + 2, x + 3, x + 4
同花 : 5张牌都是相同花色的.
炸弹 : 5张牌其中有4张牌的大小相等.
三带二 : 5张牌其中有3张牌的大小相等,且另外2张牌的大小也相等.
两对: 5张牌其中有2张牌的大小相等,且另外3张牌中2张牌的大小相等.
三条: 5张牌其中有3张牌的大小相等.
一对: 5张牌其中有2张牌的大小相等.
要不起: 这手牌不满足上述的牌型中任意一个.
现在, 东东从A × B 张扑克牌中拿走了 2 张牌!分别是 (a1, b1) 和 (a2, b2). (其中a表示大小,b表示花色)
现在要从剩下的扑克牌中再随机拿出 3 张!组成一手牌!!
其实东东除了会打代码,他业余还是一个魔法师,现在他要预言他的未来的可能性,即他将拿到的“一手牌”的可能性,我们用一个“牌型编号(一个整数,属于1到9)”来表示这手牌的牌型,那么他的未来有 9 种可能,但每种可能的方案数不一样。
现在,东东的阿戈摩托之眼没了,你需要帮他算一算 9 种牌型中,每种牌型的方案数。
思路:
列出其他所有的牌,依次枚举,判断选出的三张牌与给出的两张牌组成了哪一种牌型。
判断五张牌的牌型函数为void paixing(),根据题目所给条件依次进行判断。注意不会有五张牌同时为多种牌型的情况。
接下来是枚举:一共有A* B张扑克牌,去掉给出的两张,剩下有sum=A*B-2张。i=0~sum, j=i+1~sum, k=j+1~sum,这样即可不重复地选出三张牌。之后要对这五张牌进行升序排序,便于判断牌型。
总结:
一道大模拟题,看似复杂,但只要把题目拆成几个小部分来写,就很简单。
代码:
#include <iostream>
#include <algorithm>
using namespace std;
int A,B;
int a1,b1,a2,b2;
struct card
{
int daxiao;
int huase;
card (int d=0,int h=0)
{
daxiao=d;
huase=h;
}
} c[100];
bool cmp(card c1,card c2) //按大小升序排序
{
return c1.daxiao<c2.daxiao?1:0;
}
int sum; //c数组元素个数
int ans[10]; //对应1-9编号牌型的方案数
void paixing(card c1,card c2,card c3,card c4,card c5) //按大小升序排序
{
if(c1.daxiao==c2.daxiao-1&&c2.daxiao==c3.daxiao-1&&c3.daxiao==c4.daxiao-1
&&c4.daxiao==c5.daxiao-1&&c1.huase==c2.huase&&c2.huase==c3.huase
&&c3.huase==c4.huase&&c4.huase==c5.huase)
{
ans[1]++;
return;
}
if(c1.daxiao==c2.daxiao-1&&c2.daxiao==c3.daxiao-1&&c3.daxiao==c4.daxiao-1
&&c4.daxiao==c5.daxiao-1)
{
ans[2]++;
return;
}
if(c1.huase==c2.huase&&c2.huase==c3.huase&&c3.huase==c4.huase&&c4.huase==c5.huase)
{
ans[3]++;
return;
}
if((c1.daxiao==c2.daxiao&&c2.daxiao==c3.daxiao&&c3.daxiao==c4.daxiao&&c4.daxiao!=c5.daxiao) //前四个相等
||(c1.daxiao!=c2.daxiao&&c2.daxiao==c3.daxiao&&c3.daxiao==c4.daxiao&&c4.daxiao==c5.daxiao)) //后四个相等
{
ans[4]++;
return;
}
if((c1.daxiao==c2.daxiao&&c2.daxiao==c3.daxiao&&c3.daxiao!=c4.daxiao&&c4.daxiao==c5.daxiao) //前三后二
||(c1.daxiao==c2.daxiao&&c2.daxiao!=c3.daxiao&&c3.daxiao==c4.daxiao&&c4.daxiao==c5.daxiao)) //前二后三
{
ans[5]++;
return;
}
if((c1.daxiao!=c2.daxiao&&c2.daxiao==c3.daxiao&&c3.daxiao!=c4.daxiao&&c4.daxiao==c5.daxiao) //122
||(c1.daxiao==c2.daxiao&&c2.daxiao!=c3.daxiao&&c3.daxiao!=c4.daxiao&&c4.daxiao==c5.daxiao) //212
||(c1.daxiao==c2.daxiao&&c2.daxiao!=c3.daxiao&&c3.daxiao==c4.daxiao&&c4.daxiao!=c5.daxiao)) //221
{
ans[6]++;
return;
}
if((c1.daxiao==c2.daxiao&&c2.daxiao==c3.daxiao&&c3.daxiao!=c4.daxiao&&c4.daxiao!=c5.daxiao) //311
||(c1.daxiao!=c2.daxiao&&c2.daxiao==c3.daxiao&&c3.daxiao==c4.daxiao&&c4.daxiao!=c5.daxiao) //131
||(c1.daxiao!=c2.daxiao&&c2.daxiao!=c3.daxiao&&c3.daxiao==c4.daxiao&&c4.daxiao==c5.daxiao)) //113
{
ans[7]++;
return;
}
if((c1.daxiao==c2.daxiao&&c2.daxiao!=c3.daxiao&&c3.daxiao!=c4.daxiao&&c4.daxiao!=c5.daxiao) //2111
||(c1.daxiao!=c2.daxiao&&c2.daxiao==c3.daxiao&&c3.daxiao!=c4.daxiao&&c4.daxiao!=c5.daxiao) //1211
||(c1.daxiao!=c2.daxiao&&c2.daxiao!=c3.daxiao&&c3.daxiao==c4.daxiao&&c4.daxiao!=c5.daxiao) //1121
||(c1.daxiao!=c2.daxiao&&c2.daxiao!=c3.daxiao&&c3.daxiao!=c4.daxiao&&c4.daxiao==c5.daxiao)) //1112
{
ans[8]++;
return;
}
ans[9]++;
return;
}
int main()
{
cin>>A>>B;
cin>>a1>>b1>>a2>>b2;
for(int i=0; i<10; i++) ans[i]=0;
sum=0;
card c1(a1,b1),c2(a2,b2);
//剩下的牌
for(int i=0; i<A; i++)
for(int j=0; j<B; j++)
{
if((i!=a1&&i!=a2)||(i!=a1&&j!=b2)||(j!=b1&&i!=a2)||(j!=b1&&j!=b2))
{
card theCard(i,j);
c[sum]=theCard;
sum++;
}
}
for(int i=0; i<sum; i++)
for(int j=i+1; j<sum; j++)
for(int k=j+1; k<sum; k++)
{
//进行升序排序
card P[5];
P[0]=c1,P[1]=c2,P[2]=c[i],P[3]=c[j],P[4]=c[k];
sort(P,P+5,cmp);
paixing (P[0],P[1],P[2],P[3],P[4]);
}
for(int i=1; i<=9; i++)
cout<<ans[i]<<" ";
cout<<endl;
}