【算法】蓝桥杯dfs深度优先搜索之排列组合总结

【导航】

上一篇文章 → 《【算法】蓝桥杯dfs深度优先搜索之凑算式总结》

  为了重申感谢之意,再次声明下文的大部分灵感均来自于【CSDN】梅森上校《JAVA版本:DFS算法题解两个例子(走迷宫和求排列组合数)》
  强烈大家去上面那篇文章看看,写的很好。
  下面我会列出蓝桥杯第六届B组省赛第7题、第七届第5题、第八届第4题,共3道题。

  因为他们都是:排列组合。

【第一道题】

牌型种数
  这道题可以强制转为昨天的“凑算式”类型。
  首先,强调一下题意,总共13种牌A到K,每种可以选0到4张,总共选出13张,两个13如果简单表示的话就是2 13,其中13也可以用大写的字母B表示,隐晦的透露了这道题的内涵。
  如果你还能想起来昨天“凑算式”的思路的话,那么上来第一件事肯定就是设置一个数组了
  下图是我昨天在最后一题做的总结,对于这道题来说,也适合。
步骤
  第一件事,显然这个数组的长度为13,因为我们要存13种牌,数组中只存0到4之间的数。

public static int[] a = new int[13]; 

  第二件事,这里不涉及到数字重用与否,略过。
  第三件事,定义dfs方法,还是和昨天一样,就传一个index参数

public static void dfs(int index) 

  第四件事,写递归结束条件,这里就是index == 13,越界,代表A到K我们已经取完了,接下来就是要统计一下总数是不是13张。如果是的话,就算一种,count++。

// 递归结束条件
if(index == 13) { int sum = 0; for(int i : a) { sum += i; } if(sum == 13) { count++; } return; //递归结束一定要有return啊,没有return不叫递归结束 } 

  第五件事,还未凑齐,深搜。a[]数组总共13个位置,每个位置是0到4中的一个数。代码如下:

// 搜索
for(int i=0; i<=4; i++) { a[index] = i; dfs(index+1); } 

【完整代码】

 1 public class 牌型种数dfs {
 2     public static int count = 0 ;
 3     public static int[] a = new int[13];
 4     public static void dfs(int index) {
 5         if(index == 13) {
 6             int sum = 0;
 7             for(int i : a) {
 8                 sum += i;
 9             }
10             if(sum == 13) {
11                 count++;
12             }
13             return;
14         }
15         // 搜索
16         for(int i=0; i<=4; i++) {
17             a[index] = i;
18             dfs(index+1); 
19         }
20     }
21 
22     public static void main(String[] args) {
23         dfs(0);
24         System.out.println(count); // 答案是: 3598180
25     }
26 
27 }

 

  其实我的这种解法,关键就在于对数组的使用是否熟练,用13个位置代表13个种类,每个位置只能填0到4,最后数组凑填满后,统计一下每个位置之和是否是13。
  如果你每天吃饭、睡觉、聊天都是讨论的和数组呀,dfs呀相关的,再加上看我写的文章,照着代码敲敲,那么用不了1天,准能掌握这种套路。

  这篇文章的标题是关于排列组合的,之所以开个新坑,就是想告诉大家,虽然我总结的步骤对大多数dfs类型的题有用,但是不要局限以为只有那样的模式才算是dfs。
  比如同样是这道题,同样是dfs算法,但是代码却不一样。下面的代码参考自【CSDN】h1021456873《蓝桥杯 牌型种数 (暴力||dfs)》

 1 public static int count = 0 ;
 2 public static void dfs(int type, int sum) {
 3     // 结束条件
 4     if(type == 13) { // A到K  13类
 5         if(sum == 13) { // 要凑够13张
 6             count++;
 7         }
 8         return;
 9     }
10     // 搜索
11     for(int i=0; i<=4; i++) {
12         dfs(type+1, sum+i); // 此解法的关键,就在于sum+i 而不是sum+1
13     }
14 }
15 
16 public static void main(String[] args) {
17     dfs(0,0);
18     System.out.println(count);
19 }

 

  可以看到这个dfs方法传入了两个参数,上面的代码没有像我那样使用数组,如果看懂我的代码,这个也挺好理解的。
  之所以要说上面的代码是要引出来下面这道题

【第二道题】

第二道题
  这是一道填空题,给出的代码如下,其中的注释是我添加的

 1 public class 抽签dfs {
 2     
 3     public static void f(int[] a, int k, int n, String s) {
 4         // 结束条件
 5         if (k == a.length) {
 6             if (n == 0)
 7                 System.out.println(s);
 8             return;
 9         }
10         // 搜索
11         String s2 = s;
12         for (int i = 0; i <= a[k]; i++) {
13             _________________________// 填空位置
14             s2 += (char) (k + 'A');
15         }
16     }
17 
18     public static void main(String[] args) {
19         int[] a = { 4, 2, 2, 1, 1, 3 };
20         f(a, 0, 5, "");
21     }
22 }

 

  我还清楚的记得我第一次做这道题,当时我还不知道什么是dfs深度优先搜索,压根没看出来这代码什么意思,只是觉得应该递归。经过上篇文章的磨练,现在可以一眼看出这就是dfs的代码套路,只不过他传的参数有点多,4个。
  这道题13分,这种填空题一定不能莽撞,他给出了程序代码,自己填上答案之后,可以结合题意验证一下,比如这道题他有说明总共会输出101行结果,这就是一个检验条件。
  我第一次做的时候,完全是蒙的答案,如下:

f(a, k++, n, s2); //错误示例 

正确答案

f(a, k + 1, n - i, s2); 

  很显然,我当时没有搞懂dfs的搜索代码,即下列代码

for (int i = 0; i <= a[k]; i++) { _________________________// 填空位置 s2 += (char) (k + 'A'); } 

  既然他在main方法中调用了dfs算法,参数n传入的是5,那么就代表观察团的总人数要求是5人,这里的for循环进行搜索,一但选中 i 个人,那么接下来只能选 n - i 个人,所以参数应该是n - i,而不是n
  还有一点就是对于深搜这种,下一个情况是k+1,而不能用k++,或++k。原因是数组会越界,至于为什么会越界,我自己分析了一下,没搞懂。最后就硬记住了,这就是套路,请按套路出牌。
  说实话,这道题如果不是填空题,而是一道大题,尽管我自认为理解了dfs算法,但还是写不对代码。还是要多理解理解这道题。

【第三道题】

  这篇文章的最后一道题
魔方状态
  先说明,这道题到底怎么解,其实我也不知道,在这里写它的原因是看到了下面这篇文章,不过作者说的答案:216,作者明知11112233和33221111是同一种知道去重,却没说出来12233111 和 11133221这样之类的也是同一种,因此对于他的答案我不敢苟同。
【CSDN】sangjinchao《第八届蓝桥杯JAVAB组第四题》
  不过,就11112233全排列,这一单纯的知识点我是很感兴趣的。
  下面我想讨论一下使用dfs算法就给定数字全排列问题,比如上面的数字四个1两个2两个3进行全排列,我使用了标记法,写的代码如下

 1 public class 全排列dfs {
 2 
 3     public static int[] a = new int[] { 1, 1, 1, 1, 2, 2, 3, 3 };
 4     public static int[] visited = new int[8];
 5     public static int[] result = new int[8];
 6     public static void dfs(int index) {
 7         // 结束条件
 8         if (index == 8) {
 9             for (int i : result) {
10                 System.out.print(i);
11             }
12             System.out.println();
13             return;
14         }
15         // 搜索
16         for(int i=0; i<8; i++) {
17             if(visited[i]==0) {
18                 visited[i] = 1;
19                 result[index] = a[i];
20                 dfs(index+1);
21                 visited[i] = 0;
22             }
23         }
24     }
25 
26     public static void main(String[] args) {
27         dfs(0);
28     }
29 
30 }

 

  不过,有些情况11112233和33221111,还有11221133和33112211这类的都算重复的,所以需要去掉。目前我给出一个不太成熟的代码,只能想到这里了,如果有谁有优化的代码,一定要给我打call告诉我

 1 public class 全排列dfs逆置去重 {
 2 
 3     public static int[] a = new int[] { 1, 1, 1, 1, 2, 2, 3, 3 };
 4     public static int[] visited = new int[8];
 5     public static int[] result = new int[8];
 6     public static int[] res = new int[33221112];
 7     public static int count = 0;
 8     public static void dfs(int index) {
 9         // 结束条件
10         if (index == 8) {
11             String s = "";
12             String rev = "";
13             StringBuilder sb= new StringBuilder();
14             for (int i : result) {
15                 sb.append(i);
16             }
17             s = sb.toString();
18             rev = sb.reverse().toString(); // 逆置
19             if(res[Integer.parseInt(rev)] == 0) {// 去重
20                 res[Integer.parseInt(s)] = 1;
21                 System.out.println(s);
22                 count++;
23             }
24             return;
25         }
26         // 搜索
27         for(int i=0; i<8; i++) {
28             if(visited[i]==0) {
29                 visited[i] = 1;
30                 result[index] = a[i];
31                 dfs(index+1);
32                 visited[i] = 0;
33             }
34         }
35     }
36 
37     public static void main(String[] args) {
38         dfs(0);
39         System.out.println(count);
40     }
41 
42 }

 

  这篇文章到这里就该结束了,我的初衷就是想告诉大家,dfs不仅仅是我在上篇文章里面写的那篇,只能计算“凑算式”,dfs身为一种暴力破解方法,有很多种变形,还需要大家多加练习。
  有些人会担心,都这个时候了复习蓝桥杯,迟吗?送你一句话:Latter Better Than Never!
  
  上一篇文章 → 《【算法】蓝桥杯dfs深度优先搜索之凑算式总结》

  下一篇文章预计会在周五更新 → 《【算法】蓝桥杯dfs深度优先搜索之图连通总结》
  


参考文章:

    【CSDN】h1021456873《蓝桥杯 牌型种数 (暴力||dfs)》

    【CSDN】豌豆苞谷《2017 第八届蓝桥杯 魔方状态》

    【CSDN】sangjinchao《第八届蓝桥杯JAVAB组第四题》

转载于:https://www.cnblogs.com/littlecurl/p/10575638.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/483866.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

人工神经网络能否驾驭生物神经元的“浓稠”程度?5到8层可能并非极限

来源&#xff1a;图灵人工智能编译&#xff1a;李扬霞编辑&#xff1a;青暮计算神经科学家通过训练人工神经网络来模仿生物神经元&#xff0c;提供了一种探讨单个脑细胞复杂性的新方法。虽然我们糊状的大脑似乎与计算机处理器中的芯片大相径庭&#xff0c;但科学家对两者的比较…

困扰爱因斯坦的「幽灵般的超距作用」,是如何被贝尔定理证明确实存在的?...

文章来源&#xff1a;机器之心作者&#xff1a;Ben Brubaker原文链接&#xff1a;https://www.quantamagazine.org/how-bells-theorem-proved-spooky-action-at-a-distance-is-real-20210720/我们理所当然地认为&#xff0c;世界上某个地方发生的一件事不会立即对远方的事物产生…

Jupyter notebook 导入和卸载 conda 虚拟环境

一、导入 进入Anaconda Prompt&#xff0c;激活要使用的虚拟环境。 conda activate xxx # 你要使用的虚拟环境名称安装 ipykernel 插件&#xff0c; 建议使用 pip 进行安装&#xff0c; conda 安装容易失败 pip install ipykernel安装完成之后&#xff0c;键入以下命令 pyt…

处理器管理与进程管理

4.python练习 1.观察父进程、子进程 2.观察进程运行状态 3。输入多个作业的作业编号&#xff0c;到达时间&#xff0c;所需CPU时间&#xff0c;形成列表&#xff0c;以备算法使用。 转载于:https://www.cnblogs.com/hclhechunlu/p/10580946.html

小白 LeetCode 242 有效的字母异位词

字母异位词 字符串由相同字母组成&#xff0c;但允许排列顺序不同。 如“aaabbb” 与 “ababab” 是字母异位词&#xff0c; 而“aabb” 与 “ab” 不是字母异位词。 题目&#xff1a;给定两个字符串 s 和 t &#xff0c;编写一个函数来判断 t 是否是 s 的字母异位词。 示例…

LSTM之父:吐槽了两年,来划划重点:“这5篇最高引论文都源于我们。”

来源&#xff1a;AI科技评论作者&#xff1a;陈彩娴编辑&#xff1a;青暮昨晚&#xff0c;“递归神经网络之父”Jrgen Schmidhuber 在推特上亲自发文&#xff0c;称目前引用数最高的5项神经网络工作都基于他的团队成果&#xff0c;一时引起了网友的广泛讨论。这并不是他首次发声…

初学者配置环境变量

1. 首先选择计算机右击&#xff0c;选择最后一个属性&#xff0c;进入属性面板 2. 点击“高级系统设置”&#xff0c;点击“环境变量” 3. 在“系统变量”的处配置所需要配置的环境变量&#xff0c;点击“新建”按钮 4. 配置java的环境变量 JAVA_HOME 、CLASSPATH 、 Path5. JA…

小白 LeetCode 5605 检查两个字符串数据是否相等

题目&#xff1a;给你两个字符串数组 word1 和 word2 。如果两个数组表示的字符串相同&#xff0c;返回 true &#xff1b;否则&#xff0c;返回 false 。 数组表示的字符串 是由数组中的所有元素 按顺序 连接形成的字符串。 示例 1&#xff1a; 输入&#xff1a;word1 [&q…

Mac OS X下Maven的安装与配置

Mac OS X下Maven的安装与配置&#xff1a; 下载maven&#xff1a;https://maven.apache.org/download.cgi 打开Terminal,输入以下命令&#xff0c;设置Maven classpath&#xff0c;输入命令 vim ~/.bash_profile&#xff08;编辑环境变量配置文件&#xff09; MAVEN_HOME/…

演讲实录丨吴朝晖院士:从AI到CI——脑机智能的发展

来源&#xff1a;中国人工智能学会原创 &#xff1a;CAAI作者&#xff1a;吴朝晖院士吴朝晖中国科学院院士浙江大学校长IEEE/CAAI/CCF/CAA Fellow以下是吴朝晖院士的演讲实录&#xff1a;21世纪被称为“脑研究世纪”&#xff0c;伴随着脑科学和认知科学的兴起&#xff0c;特别是…

LeetCode 1480 一维数组的动态和

题目&#xff1a; 给你一个数组 nums 。数组「动态和」的计算公式为&#xff1a;runningSum[i] sum(nums[0]…nums[i]) 。 请返回 nums 的动态和。 示例 1&#xff1a; 输入&#xff1a;nums [1,2,3,4] 输出&#xff1a;[1,3,6,10] 解释&#xff1a;动态和计算过程为 [1,…

推荐系统简介

推荐系统简介 文章目录推荐系统简介1.推荐系统概述推荐系统目的我们推荐的目的&#xff1a;推荐系统的应用推荐系统的基本思想推荐系统的数据分析推荐系统分类2.推荐系统简介基于人口统计学的推荐基于内容的推荐基于协同过滤的推荐混合推荐3.推荐系统评测推荐系统的实验方法推荐…

清华大学孙茂松:透过喧嚣,坐看云起,NLP 的迷思与感悟

来源&#xff1a;智源社区图源&#xff1a;澎湃新闻2010年深层神经网络在语音识别研究方向上取得里程碑式进展&#xff0c;以这一事件为新起点和新动能&#xff0c;整个人工智能领域迅速跃迁到深度学习时代&#xff0c;包括自然语言处理&#xff08;NLP&#xff09;等关键领域也…

2022年科学突破奖,9人共获奖金1500万美元,mRNA 新冠疫苗2位奠基人获奖

来源&#xff1a;科研圈编辑&#xff1a;David9 月 9 日&#xff0c;2022 年科学突破奖获奖名单在美国旧金山公布。生命科学奖、物理学奖、数学奖分别授予 5 个项目共 9 位科学家&#xff0c;每个项目奖金金额为 300 万元。新冠 mRNA 疫苗技术奠基者 Katalin Karik 与 Drew Wei…

多巴胺如何驱使我们克服复杂情况、逆境、情绪, 让我们掌控周遭的环境的

来源&#xff1a;本文摘自《贪婪的多巴胺》仅仅是“想要”很少能让你得到任何东西。你必须弄清楚如何获得它&#xff0c;以及它是否值得拥有。事实上&#xff0c;如果我们做事时不考虑怎么做和下一步做什么&#xff0c;失败甚至不是最坏的结果。结果可能从吃得有点儿多发展为不…

火爆股市的元宇宙,究竟关VR/AR什么事?

来源&#xff1a;VR每日必看VR设备被普遍认为是进出元宇宙的主要终端&#xff0c;据Wind数据&#xff0c;VR概念的上市公司包括歌尔股份、中科创达、欣旺达等55家公司。大洋彼岸的“蝴蝶”扇动翅膀&#xff0c;A股的元宇宙概念也火热起来。A股代表性企业中青宝已经连续两日“20…

2018-2019-2 网络对抗技术 20165301 Exp2 后门原理与实践

2018-2019-2 网络对抗技术 20165301 Exp2 后门原理与实践 实验内容 (1)使用netcat获取主机操作Shell&#xff0c;cron启动(2)使用socat获取主机操作Shell, 任务计划启动(3)使用MSF meterpreter&#xff08;或其他软件&#xff09;生成可执行文件&#xff0c;利用ncat或socat传送…

世界机器人大会|人工智能VS人类

来源&#xff1a;新华社作者&#xff1a;北京邮电大学人工智能学院 刘伟配音&#xff1a;郑琬策划、终审&#xff1a;刘君校对&#xff1a;周雪晴2021世界机器人大会于9月10日至13日在北京召开&#xff0c;世界机器人博览会及世界机器人大赛将同期举办。其实&#xff0c;智能不…

LeetCode LCP 06. 拿硬币

题目&#xff1a;桌上有 n 堆力扣币&#xff0c;每堆的数量保存在数组 coins 中。我们每次可以选择任意一堆&#xff0c;拿走其中的一枚或者两枚&#xff0c;求拿完所有力扣币的最少次数。 示例 1&#xff1a; 输入&#xff1a;[4,2,1]输出&#xff1a;4解释&#xff1a;第一…

华为:憧憬6G,共同定义6G

来源&#xff1a;华为华为心声社区发布了由徐直军签发的总裁办电子邮件&#xff0c;邮件内容为徐直军为《6G无线通信新征程》一书作的序《憧憬6G&#xff0c;共同定义6G》。徐直军在文中表示&#xff0c;6G将在2030年左右投向市场&#xff0c;究竟市场将会迎来什么样的6G&#…