天天看点

第六届蓝桥杯个人省赛C语言A组第六题牌型种数

牌型种数

小明被劫持到X赌城,被迫与其他3人玩牌。

一副扑克牌(去掉大小王牌,共52张),均匀发给4个人,每个人13张。

这时,小明脑子里突然冒出一个问题:

如果不考虑花色,只考虑点数,也不考虑自己得到的牌的先后顺序,自己手里能拿到的初始牌型组合一共有多少种呢?

请填写该整数,不要填写任何多余的内容或说明文字。

答案:3598180

对于A,2,3…J、Q、K这13种牌,小明拿到每种牌的张数可能为0、1、2、3或4张牌。共有5的13次方(1 220 703 125)种可能性,但其中只有每种牌张数总和为13的组合才为正确的组合,该组合数为3 598 180。

解法一

#include <iostream> 
#include <cstdio>
#include <cstring> 
#include <algorithm> 
#include <cctype> 
#include <vector> 
#include <cstdlib>

using namespace std; 

int main() 
{
int i[20]; 
    long long ans=0; 

    for(i[1]=0;i[1]<=4;i[1]++) 
        for(i[2]=0;i[2]<=4;i[2]++)
            for(i[3]=0;i[3]<=4;i[3]++)
                for(i[4]=0;i[4]<=4;i[4]++)
                    for(i[5]=0;i[5]<=4;i[5]++) 
                        for(i[6]=0;i[6]<=4;i[6]++) 
                            for(i[7]=0;i[7]<=4;i[7]++) 
                                for(i[8]=0;i[8]<=4;i[8]++) 
                                    for(i[9]=0;i[9]<=4;i[9]++) 
                                        for(i[10]=0;i[10]<=4;i[10]++) 
                                            for(i[11]=0;i[11]<=4;i[11]++) 
                                                for(i[12]=0;i[12]<=4;i[12]++) 
                                                    for(i[13]=0;i[13]<=4;i[13]++) 
                                                    {
                                                        int t=0; 
                                                        for(int j=1;j<=13;j++) 
                                                        { 
                                                            t+=i[j]; 
                                                        } 
                                                        if(t==13) 
                                                        {
                                                            ans++;
                                                        }
                                                    } 
    cout<<ans<<endl; 
    system("pause"); 
    return 0; 
}           

解法二

#include<iostream>

using namespace std;

void perm(int cur, int& ctr, int sum); 

int main()
{
    int ctr=0;
    int sum=0;

    perm(1,ctr,sum);

    cout<<ctr<<endl;

    return 0;
} 

/**
*cur为当前考虑到哪种牌,cur=1即考虑牌型为A的情况
*ctr统计正确的组合数
*sum统计当前牌的总数是否已经超过13,如超过则无需继续考虑子节点
*/ 
void perm(int cur, int& ctr, int sum)
{
    if(sum>13)       
        return;
    if(cur==14)     //易错点,要将K(第13张牌)考虑完,即cur=14 
    {
        if(sum==13) //易错点,排除总和不为13的组合方式 
            ctr++;
    }
    else
    {
        for(int i=0; i<=4; i++)
        {
            sum+=i;
            perm(cur+1,ctr,sum);
            sum-=i;
        }
    }
}           

解法二的效率要明显优于解法一的效率。

继续阅读