(六省)蓝桥真题 牌型种数

牌型种数

小明被劫持到X赌城,被迫与其他3人玩牌。
一副扑克牌(去掉大小王牌,共52张),均匀发给4个人,每个人13张。
这时,小明脑子里突然冒出一个问题:
如果不考虑花色,只考虑点数,也不考虑自己得到的牌的先后顺序,自己手里能拿到的初始牌型组合一共有多少
种呢?

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

解析:只考虑点数,则13张牌中某点数的牌数最少有0张,最多有4张。

答案:3598180

方法一:暴力求解

#include <iostream>
using namespace std; 
/* run this program using the console pauser or add your own getch, system("pause") or input loop */

int main(int argc, char** argv) {
	int count = 0;
	for(int A1 = 0; A1 <= 4; A1++)
		for(int A2 = 0; A2 <= 4; A2++)
			for(int A3 = 0; A3 <= 4; A3++)
				for(int A4 = 0; A4 <= 4; A4++)
					for(int A5 = 0; A5 <= 4; A5++)
						for(int A6 = 0; A6 <= 4; A6++)
							for(int A7 = 0; A7 <= 4; A7++)
								for(int A8 = 0; A8 <= 4; A8++)
									for(int A9 = 0; A9 <= 4; A9++)
										for(int A10 = 0; A10 <= 4; A10++)
											for(int AJ = 0; AJ <= 4; AJ++)
												for(int AQ = 0; AQ <= 4; AQ++)
													for(int AK = 0; AK <= 4; AK++)
													{
														if(A1+A2+A3+A4+A5+A6+A7+A8+A9+A10+AJ+AQ+AK == 13)
														{
															count++;
														}
													}
	cout<<count<<endl;
	return 0;
}

方法二:DFS 以牌的点数深度遍历

深度遍历退出条件:

1. 牌数目大于13张,直接退出

2. 牌点数达到13点时,牌数目正好13张,计数加一,退出

深度遍历条件:牌点数未达到13点,牌数目未达到13张

#include <iostream>
using namespace std; 
/* run this program using the console pauser or add your own getch, system("pause") or input loop */

int count = 0;
 
//以牌的类型深度遍历 
void dfs(int cardNum,int sum)
{//点数,当前手里的牌数 
	if(sum > 13) 
		return;
	if(cardNum == 13)
	{
		if(sum == 13)//遍历了所有点的牌,手里正好13张牌时满足条件 
			count++;return; 
	}
	for(int i = 0; i <= 4; i++)
	{
		dfs(cardNum + 1,sum + i);
        //上句功能同下三句作用相同
		//sum += i;
		//dfs(cardNum +1,sum);
		//sum -= i; //还原 
	}
}

int main(int argc, char** argv) {
	
	dfs(0,0);
	cout<<count<<endl;
	return 0;
}

方法三:提高DFS效率

深度遍历退出条件:

1.牌数目达到13张,计数加一,退出

2.牌数目不足13张,牌点数达到13点,直接退出

深度遍历条件:

  牌数目不足13张,同时牌点数达到13点

效率提高点:(看代码)

#include <iostream>
using namespace std; 
//* run this program using the console pauser or add your own getch, system("pause") or input loop */

int count = 0;
// 
//以牌的类型深度遍历 
void dfs(int cardNum,int sum)//参数一:点数; 参数二:当前手里的牌数 
{
	if(sum == 13)
	{//手里正好13张牌时满足条件 
		count++;
		return; 
	}
	if(cardNum==13) {  
          return; //遍历完所有点数依旧补够13张,返回,满足条件的情况次数不变  
        } 

        //当剩余牌数小于4时,就可以减少多余遍历路径,提高BFS效率
	//同时不会出现sum > 13 的情况 
	int num = min(13-sum,4);
	for(int i = 0; i <= num; i++)
	{
		dfs(cardNum + 1,sum + i); 
	}
	return; 
} 
int main(int argc, char** argv) {
	
	dfs(0,0);
	cout<<count<<endl;
	return 0;
}
  

借鉴:

https://blog.csdn.net/h1021456873/article/details/50876381

https://www.cnblogs.com/lemonbiscuit/p/7776009.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值