题目:

小明被劫持到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题,牌型种数,一道简单的题带来的思考的更多相关文章

  1. 第九届蓝桥杯JavaA组省赛真题

    解题代码部分来自网友,如果有不对的地方,欢迎各位大佬评论 题目1.分数 题目描述 1/1 + 1/2 + 1/4 + 1/8 + 1/16 + - 每项是前一项的一半,如果一共有20项, 求这个和是多 ...

  2. 第六届蓝桥杯JavaA组国(决)赛真题

    解题代码部分来自网友,如果有不对的地方,欢迎各位大佬评论 题目1.胡同门牌号 小明家住在一条胡同里.胡同里的门牌号都是连续的正整数,由于历史原因,最小的号码并不是从1开始排的. 有一天小明突然发现了有 ...

  3. 第六届蓝桥杯JavaA组省赛真题

    解题代码部分来自网友,如果有不对的地方,欢迎各位大佬评论 题目1.熊怪吃核桃 题目描述 森林里有一只熊怪,很爱吃核桃.不过它有个习惯,每次都把找到的核桃分成相等的两份,吃掉一份,留一份.如果不能等分, ...

  4. 第七届蓝桥杯JavaA组国(决)赛部分真题

    解题代码部分来自网友,如果有不对的地方,欢迎各位大佬评论 题目1.阶乘位数 阶乘位数 9的阶乘等于:362880 它的二进制表示为:1011000100110000000 这个数字共有19位. 请你计 ...

  5. 第七届蓝桥杯JavaA组省赛真题

    解题代码部分来自网友,如果有不对的地方,欢迎各位大佬评论 题目1.煤球数量 煤球数目 有一堆煤球,堆成三角棱锥形.具体: 第一层放1个, 第二层3个(排列成三角形), 第三层6个(排列成三角形), 第 ...

  6. 2018年第九届蓝桥杯B组题C++汇总解析-fishers

    2018年第九届蓝桥杯B组题C++解析-fishers 题型 第一题:第几天 第二题:明码 第三题:乘积尾零 第四题:测试次数 第五题:快速排序 第六题:递增三元组 第七题:螺旋折线 第八题:日志统计 ...

  7. 第十届蓝桥杯JavaB组省赛真题

    试题 A: 组队 本题总分:5 分 [问题描述] 作为篮球队教练,你需要从以下名单中选出 1 号位至 5 号位各一名球员, 组成球队的首发阵容. 每位球员担任 1 号位至 5 号位时的评分如下表所示. ...

  8. 2015年第六届蓝桥杯JavaB组省赛试题解析

    题目及解析如下: 题目大致介绍: 第一题到第三题以及第六题.第七题是结果填空,方法不限只要得到最后结果就行 第四题和第五题是代码填空题,主要考察算法基本功和编程基本功 第八题到第十题是编程题,要求编程 ...

  9. 第十届蓝桥杯JavaB组总结

    去年参加了第九届蓝桥杯C/C++B组,很捞,做了大概5道题,就好像就做对了2道结果填空题,编程题只做了一个(只通过了部分测试数据),最后拿了个省三,但是班上那些平时没有认真准备的都拿了省二 今年想好好 ...

随机推荐

  1. 已Access为支持,书写一个C#写入的记录的方案

      /// <summary> /// 读取Excel文档 /// </summary> /// <param name="Path">文件名称 ...

  2. Emacs杂谈(一)Emacs环境 c++ 快捷键

    最近头脑发热(抽),重装了电脑,改成linux的ubuntu系统,熟悉一下环境,顺便转载相关emacs知识. //插播一则通知:似乎linux上vector不能用,会内存炸错,若有人可以解答,请用评论 ...

  3. Javascript异步编程的4种方法

    你可能知道,Javascript语言的执行环境是"单线程"(single thread).   所谓"单线程",就是指一次只能完成一件任务.如果有多个任务,就必 ...

  4. pullRefresh组件配置

    mui.init({ pullRefresh:{ container: '#contanier', indicators:false, up:{ height:200, contentinit: '' ...

  5. Integer.parseInt(String s) 和 Integer.valueOf(String s) 的区别

    通过查看java.lang.Integer的源码可以发现, 它们最终调用的都是 /** * Parses the string argument as a signed integer in the ...

  6. PHP高效率写法及原因

    1.尽量静态化: 如果一个方法能被静态,那就声明它为静态的,速度可提高1/4,甚至我测试的时候,这个提高了近三倍. 当然了,这个测试方法需要在十万级以上次执行,效果才明显. 其实静态方法和非静态方法的 ...

  7. PAT 1031. 查验身份证(15)

    一个合法的身份证号码由17位地区.日期编号和顺序编号加1位校验码组成.校验码的计算规则如下: 首先对前17位数字加权求和,权重分配为:{7,9,10,5,8,4,2,1,6,3,7,9,10,5,8, ...

  8. Lobes of the brain

    Source: https://en.wikipedia.org/wiki/Lobes_of_the_brain (Except for the last figure) Terminologia A ...

  9. SQL Server 2005、2008 的 datetime 值范围(转)

    SQL Server 2005.2008 的 datetime 最小值是:1753-01-01 00:00:00 最大值是:9999-12-31 23:59:59.997 这与 .NET 中的 Dat ...

  10. [转]一篇很全面的freemarker教程

    copy自http://demojava.iteye.com/blog/800204 以下内容全部是网上收集: FreeMarker的模板文件并不比HTML页面复杂多少,FreeMarker模板文件主 ...