第6届蓝桥杯javaA组第7题,牌型种数,一道简单的题带来的思考
题目:
小明被劫持到X赌城,被迫与其他3人玩牌。
一副扑克牌(去掉大小王牌,共52张),均匀发给4个人,每个人13张。
这时,小明脑子里突然冒出一个问题:
如果不考虑花色,只考虑点数,也不考虑自己得到的牌的先后顺序,自己手里能拿到的初始牌型组合一共有多少种呢?
请填写该整数,不要填写任何多余的内容或说明文字。
拿到这道题的时候第一时间想到了解决方案:dfs。
但是我在编写第一版的时候出现了很大的问题,导致算法复杂度为O(n^n),当然,这道题目里面的n自然就是13了。
我的想法是:从第一张牌开始取,一直取到第13张,而每一次取牌呢,是在13种牌里面遍历,用一个数组记录每一种牌目前被取了多少,在遍历中看这个牌被取得数目是不是大于4,是的话就不取这张牌。
然而这么做直接导致13的循环里面每一次都有13种可能,再加上排列组合,一共13^13种需要遍历。
代码如下:
import java.util.Arrays; public class Main_1 { public static void main(String[] args) {
Solution s = new Solution();
int[] numStates = new int[13];
s.recurse(0, numStates);
System.out.println(s.allPos);
}
}
class Solution {
int allPos = 0;
public void recurse(int curStep, int[] numStates) {
if(curStep == 13) {
allPos++;
System.out.println(Arrays.toString(numStates));
}
else {
for(int i = 2; i < 15; i++) {
if(numStates[i - 2] < 4) {
numStates[i - 2]++;
recurse(curStep + 1, numStates);
numStates[i - 2]--;
}
}
}
}
}
第一版的直接运行结果是半天没有反应,我一开始以为它陷入死循环了,结果用“System.out.println(Arrays.toString(numStates));”一看,发现一直在跑,但是过于复杂了。
我看到这个结果以为不能用暴力法破解,然后去网上看看别人的做法,发现有人用暴力法成功了,我大致看了别人的代码之后发现我的问题可能出自暴力法之中。
第二版我的想法是:还是递归13次,不过这次递归的是每一种牌的取得个数。也就是在13次的递归之中,每一次研究当前这种牌能取多少(具体一点就是比如说该考虑8这张牌了,那么有5种可能,从一张不拿到四张全拿),当递归次数达到13时,直接比较当前牌的总数是不是13。当然优化的方法是直接把另外一个条件也作为结束递归的标志:“目前的牌的总数大于了13,那么之后就算全部不取都无法满足条件”。算法复杂度是O(5^n),这道题目里面n = 13;
代码如下:
public class Main_2 { public static void main(String[] args) {
Solution_2 s = new Solution_2();
s.getResult(0, 0);
System.out.println(s.num);
}
} class Solution_2 {
public int num = 0;
public void getResult(int curSum, int curStep) {
if(curStep == 13 || curSum > 13) {
if(curSum == 13)
num++;
}
else {
for(int i = 0; i <= 4; i++) {
getResult(curSum + i, curStep + 1);
}
}
}
}
这道题目给我的思考是,在用暴力法的时候直接多想几种可能,多想几种优化方案,这样可以很大程度上节约时间
第6届蓝桥杯javaA组第7题,牌型种数,一道简单的题带来的思考的更多相关文章
- 第九届蓝桥杯JavaA组省赛真题
解题代码部分来自网友,如果有不对的地方,欢迎各位大佬评论 题目1.分数 题目描述 1/1 + 1/2 + 1/4 + 1/8 + 1/16 + - 每项是前一项的一半,如果一共有20项, 求这个和是多 ...
- 第六届蓝桥杯JavaA组国(决)赛真题
解题代码部分来自网友,如果有不对的地方,欢迎各位大佬评论 题目1.胡同门牌号 小明家住在一条胡同里.胡同里的门牌号都是连续的正整数,由于历史原因,最小的号码并不是从1开始排的. 有一天小明突然发现了有 ...
- 第六届蓝桥杯JavaA组省赛真题
解题代码部分来自网友,如果有不对的地方,欢迎各位大佬评论 题目1.熊怪吃核桃 题目描述 森林里有一只熊怪,很爱吃核桃.不过它有个习惯,每次都把找到的核桃分成相等的两份,吃掉一份,留一份.如果不能等分, ...
- 第七届蓝桥杯JavaA组国(决)赛部分真题
解题代码部分来自网友,如果有不对的地方,欢迎各位大佬评论 题目1.阶乘位数 阶乘位数 9的阶乘等于:362880 它的二进制表示为:1011000100110000000 这个数字共有19位. 请你计 ...
- 第七届蓝桥杯JavaA组省赛真题
解题代码部分来自网友,如果有不对的地方,欢迎各位大佬评论 题目1.煤球数量 煤球数目 有一堆煤球,堆成三角棱锥形.具体: 第一层放1个, 第二层3个(排列成三角形), 第三层6个(排列成三角形), 第 ...
- 2018年第九届蓝桥杯B组题C++汇总解析-fishers
2018年第九届蓝桥杯B组题C++解析-fishers 题型 第一题:第几天 第二题:明码 第三题:乘积尾零 第四题:测试次数 第五题:快速排序 第六题:递增三元组 第七题:螺旋折线 第八题:日志统计 ...
- 第十届蓝桥杯JavaB组省赛真题
试题 A: 组队 本题总分:5 分 [问题描述] 作为篮球队教练,你需要从以下名单中选出 1 号位至 5 号位各一名球员, 组成球队的首发阵容. 每位球员担任 1 号位至 5 号位时的评分如下表所示. ...
- 2015年第六届蓝桥杯JavaB组省赛试题解析
题目及解析如下: 题目大致介绍: 第一题到第三题以及第六题.第七题是结果填空,方法不限只要得到最后结果就行 第四题和第五题是代码填空题,主要考察算法基本功和编程基本功 第八题到第十题是编程题,要求编程 ...
- 第十届蓝桥杯JavaB组总结
去年参加了第九届蓝桥杯C/C++B组,很捞,做了大概5道题,就好像就做对了2道结果填空题,编程题只做了一个(只通过了部分测试数据),最后拿了个省三,但是班上那些平时没有认真准备的都拿了省二 今年想好好 ...
随机推荐
- 那些强悍的PHP一句话后门
强悍的PHP一句话后门这类后门让网站.服务器管理员很是头疼,经常要换着方法进行各种检测,而很多新出现的编写技术,用普通的检测方法是没法发现并处理的.今天我们细数一些有意思的PHP一句话木马.利用404 ...
- 在C++中实现字符串分割--split
字符串分割 在一些比较流行的语言中,字符串分割是一个比较重要的方法,不论是在python,java这样的系统级语言还是js这样的前端脚本都会在用到字符串的分割,然而在c++中却没有这样的方法用来调用. ...
- 用css画实心三角形
.arrow-down:after{ content: ''; position: relative; top: 12px; left: 2px; border-style: solid; borde ...
- QQ浏览器X5内核问题汇总
原文:http://itindex.net/detail/53391-qq-浏览器-x5 常常被人问及微信中使用的X5内核的问题,其实我也不是很清楚,只知道它是基于android 4.2的webkit ...
- Asp.net,C# 纯数字加密解密字符串
也就是说加密后的数据不再是:N8lAaHMFtSAQgaf3+RUFng== 希望encryptedString是"1203877893704809384098328409234923840 ...
- 学习C++.Primer.Plus 5 循环和关系表达式
C++将赋值表达式的值定义为左侧成员的值 赋值操作符是自右向左结合的 cout.setf(ios:: boolalpha);//调用设置标记,命令cout输出true或false,而非1或0. 任何表 ...
- Theano2.1.6-基础知识之在thenao中的求导
来自:http://deeplearning.net/software/theano/tutorial/gradients.html Derivatives in Theano 一.计算梯度 现在,让 ...
- PHP核心编程知识点
一.PHP基本语法 PHP标记:一共有四种,只推荐使用第一种 语句结束符:分号 注释:行注释(// #)和块注释(/* */),注释的规范 二.常见的输出语句 print echo var_du ...
- 使用Aspose.Cells生成Excel的方法详解(转)
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System ...
- 链接错误-库冲突(libcmt.lib和libcmtd.lib)
在同一个项目中,所有的源文件必须链接相同的C运行时库.如果某一文件用了Multithreaded DLL版本,而其他文件用了Single-Threaded或者Multithreaded版本的库,也就是 ...