牌型种数
题目:
小明被劫持到X赌城,被迫与其他3人玩牌。
一副扑克牌(去掉大小王牌,共52张),均匀发给4个人,每个人13张。
这时,小明脑子里突然冒出一个问题:
如果不考虑花色,只考虑点数,也不考虑自己得到的牌的先后顺序,自己手里能拿到的初始牌型组合一共有多少种呢?
请填写该整数,不要填写任何多余的内容或说明文字。
这个题是2015年一道蓝桥杯省赛题,因为是填空题,用暴力破解是可以的,也就是说用13个for循环:
#include <iostream>
#include <cstdio>
using namespace std;
int main()
{
int a[13];
static int count;
int ans = 0;
for(a[0]=0; a[0]<=4; a[0]++)
for(a[1]=0; a[1]<=4; a[1]++)
for(a[2]=0; a[2]<=4; a[2]++)
for(a[3]=0; a[3]<=4; a[3]++)
for(a[4]=0; a[4]<=4; a[4]++)
for(a[5]=0; a[5]<=4; a[5]++)
for(a[6]=0; a[6]<=4; a[6]++)
for(a[7]=0; a[7]<=4; a[7]++)
for(a[8]=0; a[8]<=4; a[8]++)
for(a[9]=0; a[9]<=4; a[9]++)
for(a[10]=0; a[10]<=4; a[10]++)
for(a[11]=0; a[11]<=4; a[11]++)
for(a[12]=0; a[12]<=4; a[12]++)
if(a[0]+a[1]+a[2]+a[3]+a[4]+a[5]+a[6]+a[7]+a[8]+a[9]+a[10]+a[11]+a[12]==13)
{
count++;
ans = count;
}
cout<<ans<<endl;
return 0;
}
这样做带比赛的时候可以说是最快的方法。不过上面这个程序跑出结果需要3秒钟左右,oj是肯定超时的。所以我这里自己写了一个优化的程序,大概0.3秒钟可以跑出结果:
#include<stdio.h>
int sum3=0,sum1=0;//sum1:现在选到13种牌中的第几种了 sum2:现在已经拿到了第几张牌 sum3:记录有多少种可能
void comb_sum(int sum2)
{
sum1++;
if(sum2==13)
{
sum3++;
sum1--;
return;
}
else if(sum2>13)
{
sum1--;
return;
}
if(sum1==10&&sum2==0)
{
sum3+=20;
sum1--;
return;
}
else if(sum1==11&&sum2<=4)
{
if(sum2==1)
{
sum3++;
sum1--;
return;
}
else if(sum2==2)
{
sum3+=3;
sum1--;
return;
}
else if(sum2==3)
{
sum3+=6;
sum1--;
return;
}
else if(sum2==4)
{
sum3+=10;
sum1--;
return;
}
}
else if(sum1==12&&sum2<=8)
{
if(sum2==5)
{
sum3+=1;
sum1--;
return;
}
else if(sum2==6)
{
sum3+=2;
sum1--;
return;
}
else if(sum2==7)
{
sum3+=3;
sum1--;
return;
}
else if(sum2==8)
{
sum3+=4;
sum1--;
return;
}
}
else if(sum1==13&&sum2<=12)
{
sum3+=1;
sum1--;
return;
}
for(int i=sum2;i-sum2<=4;i++)
{
comb_sum(i);
}
sum1--;
return;
}
int main()
{
comb_sum(0);
printf("%d",sum3);
}
大一的初学者,所以可能写得不是很好,见笑了。