蓝桥杯算法基础(34)深度优先搜索DFS(数独游戏)(部分和)(水洼数目)(八皇后问题)(素数环)(困难的串)
深度优先搜索DFS Depth First Searchdfs:先把一条路走到黑 纵横bfs:所有路口看一遍 图 必须借助队列的数据结构无死角搜索
数独游戏
你一定听说过数独游戏
如下图所示,玩家需要根据9*9盘面上的已知数字,推理出所有剩余空格的数字,并满足每一行,每一列,每一个同色九宫内的数字均含1~9,不重复。
数独的答案都是第一的,所以,多个阶解也称为无解
本图的数字据说是芬兰数学家花了3个月的时间设计出来的较难的题目,但对会使用计算机编程的你来说,恐怕易如反掌了。
本题的要求就是输入数独题目,程序输出数独的唯一解,我们保证所有已知数据的格式都是合法的,并且题目有唯一的解
格式要求,输入9行,每行9个数字,0代表未知,其他数字为已知
输出9行,每行9个数字代表数独的解
输入:005300000
800000020
070010500
400005300
010070006
003200080
060500009
004000030
000009700程序应该输出://这道题有为一街
dfs(table,x,y){if(x==9){print(table);System.exit(0);}if(table[x][y]=='0'){//选1~9之间合法的数字到x,y这个位置for(i=1..9){boolean res=check(table,x,y,i);if(res){table[x][y]=(char)('0'+i);//转移到下一个状态dfs(table,x+(y+1)/9,(y+1)%9);//当y等于8的时候,x+1,因为x,y的位置是从0开始的,一行行的走}}//循环结束,进行回溯table[x][y]=0;}else{//继续找下一个需要处理的位置dfs(table,x+(y+1)/9,(y+1)%9);}
}public static void main(String args){Scanner sc=new Scanner(System.in);char[][] table=new char[9][];for(int i=0;i<9;i++){table[i]=sc.nextLine().toCharArray();//输入字符串,然后转成数组}dfs(table,0,0);}private static void dfs(char[][] table,int x,int y){if(x==9){//8是最大,当为9时,则意味着数组以填满print(table);System.exit(0);}if(table[x][y]=='0'){//虚位以待for(int k=0;K<10;k++){if(check(table,x,y)){table[x][y]=(char)('0'+k);dfs(table,x+(y+1)/9,(y+1)%9,k);//处理下一个状态}table[x][y]='0';//回溯}else{dfs(table,x+(y+1)/9,(y+1)%9);//处理下一个状态}}}private static boolean check(char[][] table,int i,int j,int k){for(int i=0;i<9;i++){System.out.println(new String(table[i]));}}private static boolean check(char[][] table,int i,int l,int k){//检查同行和同列for(int l=0;l<9;l++){if(table[i][l]==(char)('0'+k))return false;if(table[l][j]==(char)('0'+k))retrun false;}//检查小九宫格for(int l=(i/3)*3;l<(i/3+1)*3;l++){for(int m=(j/3)*3;m<(j/3+1)*3;m++){if(table[l][m]==(char)('0'+k))return false;}}}//m=(j/3)*3;m<(j/3+1)*3
(j/3)*3假设j为8,(j/3)前面有几个九宫格数,(j/3)*3直接回到当前九宫格最开始的位置
(j/3+1)为之前的九宫格数再加1个九宫格,(j/3+1)*3便来到当前九宫格宫格下一个九宫格的开始位置,即到这里结束
[*][] [] [*][] [] [*][] []
[] [] [] [] [] [] [] [] []
[] [] [] [] [] [] [] [] []
[*][] [] [*][] [] [*][] []
[] [] [] [] [] [] [] [] []
[] [] [] [] [] [] [] [] []
[*][] [] [*][] [] [*][] []
[] [] [] [] [] [] [] [] []
[] [] [] [] [] [] [] [] []
部分和
给定整数序列a1,a2,....,an,判断是否可以从中选出若干数,使他们和恰好为k;1<=20-10^8<ai<10^8-10^8<k<10^8输入:n=4a={1,2,4,7};k=13
输出:Yes(13=2+4+7);老思想,选与不选的问题private static void dfs(int[] a,int k,int cur,ArrayList<Integer> ints){if(k==0){System.out.println("Yes ("+kk+" = ");//kk=原始的数int size=ints.size();for(int i=0;i<size;i++){System.out.println(ints.gets(i)+(i==size-1?"":" + "));//不要最后一个"+"}System.exit(0);}if(k<||cur==a.length)return;if(k==0){}dfs(a,k,cur+1,ints);//不要cur这个元素ints.add(a[cur]);int index=ints.size()-1;dfs(a,k-a[cur],cur-1,ints);//要cur这个元素ints.remove(index);//回溯
}
水洼数目
有一个大小为N*M的园子,雨后积起了水。八联通的积水被认为是连在一起的,请求出园子里总共有多少水洼?
(八连通指的是下图中相对w的*部分)∗∗∗
∗W∗
∗∗∗10 12
W********WW*
*WWW*****WWW
****WW***WW*
*********WW*
*********W**
**W******W**
*W*W*****WW*
W*W*W*****W*
*W*W******W*
**W*******W*八连通问题
以一个W的位置为起点,找到所有的与W相连的W,每个W都有8个方向,连通在一起为一块水洼,找一共有几个水洼
走到一个位置,就将水抽掉,w->*,知道所有的水都走完public static void main(String[] args){Scanner sc=new Scanner(Systemn.in);int N=sc.nextInt();intM=sc.nextInt();char[][] a=new char[N][];for(int i=0;i<N;i++){a[i]=sc.nextLine().toCharArray();}int cnt;for(int i=0;i<N;i++){for(int j=0;j<M;j++){if(a[i][j]=='W'){dfs(a,i,j);//清除一个水洼//计数加1cnt++;//清楚之后,就继续找下一个水洼}}}System.out.println(cnt);}private static void dfs(char[][] a,int i,int j){a[i][j]='.';// if(i>0&&a[i-1][j]=='w')dfs(a,i-1;j);// if(i<a.length-1&&a[i+1][j]=='w')dfs(a,i+1;j);// if(j>0&&a[i][j-1]=='w')dfs(a,i;j-1);// if(j<a[0].length-1&&a[i][j+1]=='w')dfs(a,i;j+1);// if(i>0&&j>0&&a[i-1][j-1]=='w')dfs(a,i-1;j-1);// if(i>0&&j<a[0].length-1&&a[i-1][j+1]=='w')dfs(a,i-1;j+1);// if(i<a.length-1&&j>0&&a[i+1][j-1]=='w')dfs(a,i+1;j-1);// if(i<a.length-1&&j<a[0].length&&a[i+1][j+1]=='w')dfs(a,i+1;j+1);//用循环来表示8个方向for(int k=-1;k<2;k++){//-1 0 1for(int l=-1;k<2'k++){//-1 0 1if(k==0&&l==0)continue;//8个方向,自身跳过if(i+k>=0&&i+k<=n-1&&j+l>=0&&j+l<=m-1){if(a[i+k][j+l]=='w')dfs(a,i+k,j+l);}}}}
八皇后问题
回溯和剪枝回溯
-递归调用代表开启一个分支,如果希望这个分支返回后某些数据恢复到分支
开启前的状态,以便”重新开始“,就要使用回溯技巧
-全排列的”交换法,数独,部分和“,用到了回溯
剪枝
-深搜时,如已明确从当前状态无论如何转移都不会存在(更优)解,就应该中断往下的继续搜索,这种方法称为剪枝
-“数独”里面有剪枝
-“部分和”里面有剪枝if(限定)dfs
请设计一种算法,解决著名的n皇后问题。这里的n皇后问题指在一个n*n的棋盘上放置n个棋子
使得每行每列和每条对角线上都只有棋子,求其拜访的方法数。给定一个int n,请返回方法数,保证n小于等于15int n;
int[] rec;
int cnt;dfs(l);dfs(row){if(rec[row]==n+1){//越界后,意味着每一行都找完了cnt++;//找到一个return;}for(col from 1 to n){if(check(rec,row,col))rec[row]=col;dfs(rec,row+1);rec[row]=0;}}//x-y相同,主对角线
//x+y相同, 副对角线
check(rec,x,y){for(int i=0;i<rec.length;i++){//因为它每一行只选一个,所以不用判断横坐标if(rec[i]==y){//不能与rec数组中元素的y相同,即不能在同一列return false;}if(i+rec[i]==x+y)[//副对角线return false;}if(i-rec[i]==x-y){//主对角线return false;}}return true;
}public class Dfs_n皇后问题{int n;int count;int[] vis;public static void main(String[] agrs){n=4;、rec=new int[4];dfs(0);System.out.println(cnt);}private static void dfs(int row){if(row==n){cnt++;return;}//依此尝试在某列上放一个皇后for(int col=0;col<n;col++){boolean ok=true;//先从第一行开始for(int i=0;i<row;i++){if(rec[i]==col||i+rec[i]==row+col||row[i]-i==col-row){ok=false;break;//这一行的着一列不能放}}//这里可以认为是一个剪枝//从这一行的这一列可以放if(ok){rec[row]=col;//标记dfs(row+1);//继续找下一行//rec[row]=0;//恢复原状,这种解法这里是否恢复状态都行,为什么?//因为当前数组的长度不是rec数组的最大长度,而是依靠变化的row参数来递增和回溯的,即使当前row的后面有元素,也不必管他,只需要关注0~row之内的就行了}}}}
素数环
输入正整数n,对1~n进行排列,便得相邻两个数之和均为素数
输出时从整数1开始,逆时针排序,同一个环应恰好输出一次n<=16如输出:6
输出:
1 4 3 2 5 6
1 6 5 2 3 4//伪代码
int[] rec=new int[n];
rec[0]=1;
dfs(k){if(k==n){print(rec);return rec;}for(i from 2 to n){if(check(rec,i)){//1.i中没有在rec中出现过,2.i+rec[k-1]是一个素数rec[k]=i;dfs(k+1);rec[k]=0;}}}private static void dfs(int n,int[] r,int cur){if(cur==n&&isP(r[0]+r[n+1])){//填到末尾,还有首尾相加为素数才算成功print(r);return;}for(int 2;i<=n;i++){//尝试用每个数字填到cur这个位置上if(check(r,i,cur)){//r中没有这个数,且和上一个数之和为素数r[cur]=i;//试着将i放在cur位置,往前走一步dfs(n,r,cur+1);r[cur]=0;//回溯}}}private static boolean isP(int k){for(int i=2;i*i<=k;i++){if(k%i==0)return false;}return true;}
困难的串
问题描述:如果一个字符串包括两个相邻的重复子串,则称他为容易的串,其他串称为困难的串
如:BB,ABCDACABCAB,ABCDABCD都是容易的,A,AB,ABA,D,DC,ABDAB,CBABCBA都是困难的。输入正整数n,L,输出由前L个字符(大写英文字母)组成的,字典序第n小的困难的串
例如,当L=3时,前7个困难的串分别为:
A,AB,ABA,ABAC,ABACA,ABACAB,ABACABA
n指定为4的话,输出ABACA,AB,ABA,ABAC,ABACA,//ABACB这个不行,因为是根据字典序来排的,ABACAB比ABACB字典序要小是困难串就在后面加后缀private static void dfs(int l,int n,String prefix){//尝试在prefix后追加一个字符for(char i='A';i<'A'+l;i++){if(isHard(prefix,i)){//是困难的串,就组合起来输出String x=prefix+i;System.out.println(x);count++;//计数if(count==n)System.exit(0);dfs(l,n,x);}}
}private static boolean isHard(String prefix,char i){int count=0;//截取的宽度for(int j=prefix.length()-1;j>=0;j-=2){final String s1=prefix.substring(j,j+count+1);//从最后一个开始,随着j的往后移动,count也在逐渐增加final String s2=prefix.substring(j+count+1)+i; //j是两个两个的减,count一个一个的加,从新加入的字符的地方开始,先判断一个与一个判断是否相等,再两个两个,最后一半一半if(s1.equals(s2))return false;count++;}return true;
}
小结 -有一类问题,有明确的的递归形式,比较容易用迭代形式实现,用递归也有比较明确的层数和宽度 走楼梯,走方格,硬币表示,括号组合,子集,全排列 -有一类问题,解的空间很大(往往是阶乘级别的),要在所有可能性中找到答案,只能进行试探,尝试往前走一步,走不通在退回来,这就是dfs+回溯+剪枝 -对这类问题的优化,使用剪枝,越早剪越好,但这很难 如 素数环
相关文章:
蓝桥杯算法基础(34)深度优先搜索DFS(数独游戏)(部分和)(水洼数目)(八皇后问题)(素数环)(困难的串)
深度优先搜索DFS Depth First Searchdfs:先把一条路走到黑 纵横bfs:所有路口看一遍 图 必须借助队列的数据结构无死角搜索数独游戏 你一定听说过数独游戏 如下图所示,玩家需要根据9*9盘面上的已知数字,推理出所有剩余空格的数字,并满足每一行…...
蓝桥杯备考随手记: Math 类中常用方法
Java的Math类是一个包含数学操作方法的实用工具类。它提供了许多用于执行各种数学计算的静态方法。 下面是Math类中一些常用的方法: abs():返回参数的绝对值。 int absoluteValue Math.abs(-10); System.out.println(absoluteValue); // Output: 10 c…...
外包干了4年,技术退步明显。。。。
说一下自己的情况,本科生,19年通过校招进入上海某软件公司,干了接近4年的功能测试,今年年初,感觉自己不能够在这样下去了,长时间呆在一个舒适的环境会让一个人堕落!而我已经在一个企业干了四年的功能测试&a…...
亚远景科技-Hardware Engineering SPICE课程大纲
Hardware SPICE是intacs为电子硬件开发创建的PRM/PAM过程参考和评估模型,其符合ISO/IEC15504-2, Automotive SPICE 4.0, ISO 26262-1和5: 2018等标准。 无论您是想要深入了解硬件工程领域,还是希望成长为Provisional初级、Competent主任和Principal首席硬…...
JDK8的下载安装与环境变量配置教程
前言 官网下载:Java Archive Downloads - Java SE 8u211 and later 现在应该没人用32位的系统了吧,直接下载Windows x64 Installer jdk-8u391-windows-x64.exe 一、安装JDK 1. 打开jdk-8u391-windows-x64.exe 2. 直接下一步 3. 这个地方不要动他&…...
深入探讨分布式ID生成方案
✨✨谢谢大家捧场,祝屏幕前的小伙伴们每天都有好运相伴左右,一定要天天开心哦!✨✨ 🎈🎈作者主页: 喔的嘛呀🎈🎈 ✨✨ 帅哥美女们,我们共同加油!一起进步&am…...
花钱的艺术:消费和投资如何分配
消费是钱花出去就回不来了。 消费分为可选消费和必需消费。 必需消费是必须花的钱,用一句老话,财米油盐酱醋茶,维持生活必需的支出。 可选消费,用来提升生活水平的支出,可花可不花,比如苹果手机…...
git 代码库查看方法
在Git中,你可以使用多种命令来查看代码库(repository)的内容。以下是一些常用的命令: 查看所有分支: git branch这个命令会列出本地仓库中的所有分支。当前活动的分支前面会有一个星号(*)。 查…...
MySql的下载与安装
window系统: 下载MySQL 8.0 访问MySQL官方网站: 打开浏览器,输入网址 https://dev.mysql.com/downloads/mysql/ 进入MySQL下载页面。 选择版本: 在网页中找到“MySQL Community Server”部分,这通常是最新的社区版&am…...
python学习17:python中的while循环
python中的while循环 1.循环的作用就是:重复运行某些代码 2.while循环: 1.while的条件必须是布尔类型的 True表示继续循环,False表示结束循环 2.必须设置循环结束条件,否则将会无限循环 ,如下的count<10 如果coun…...
Android中的导航navigation的使用
Android中的导航(Navigation)是一种应用程序设计模式,它通过使用统一的用户界面来管理应用程序中的各种界面和交互。在Android中,导航主要通过使用Navigation SDK来实现,该SDK提供了一组工具和组件,可以帮助…...
Clip算法解读
论文地址:https://arxiv.org/pdf/2103.00020.pdf 代码地址:https://github.com/OpenAI/CLIPz 中文clip代码:https://gitcode.com/OFA-Sys/Chinese-CLIP/overview 一、动机 主要解决的问题: 超大规模的文本集合训练出的 NLP 模…...
使用第三方远程连接工具ssh连接vagrant创建的虚拟机
vagrant默认密码都是vagrant 密码认证默认是关闭的,进入虚拟机,打开密码认证 1、使用命令vi /etc/ssh/sshd_config进入配置,注意要切换到root用户,这个配置root有权限 2、找到PasswordAuthentication默认为no,改为yes 3、重启虚…...
linux查找指定目录下包含指定字符串文件,包含子目录
linux查找指定目录下包含指定字符串的文件,包含子目录 linux查找指定目录下包含指定字符串的指定文件格式,包含子目录 指定目录 cd /home/www/linux查找指定目录下包含指定字符串的文件,包含子目录 grep -r "指定字符串"注释 gr…...
27. BI - PageRank 的那些相关算法 - PersonRank, TextRank, EdgeRank
本文为 「茶桁的 AI 秘籍 - BI 篇 第 27 篇」 Hi, 我是茶桁. 之前咱们用两节课的时间来讲了 PageRank, 包括它的起源, 公式以及工具. 并在一个希拉里邮件的案例中用networkx完成了练习. 在上一节课中, 咱们不仅做了案例, 并且说到了 PageRank 模型的影响力, 并且讲了其中一个…...
[数据集][目标检测]公共场所危险物品检测数据集VOC+YOLO格式1431张6类别
数据集格式:Pascal VOC格式YOLO格式(不包含分割路径的txt文件,仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数):1431 标注数量(xml文件个数):1431 标注数量(txt文件个数):1431 标注…...
创业项目开发(持续更新)
最近项目梳理: 一、业务目标 最重要的业务目标就是要能实现自己做事情赚钱。所以有两个维度,第一个维度就是最重要的就是自己做事情。第二个维度才是赚钱。 如果要自己做事情,需要什么样的事情,这个事情的目标是什么࿰…...
基于SpringBoot的“校园台球厅人员与设备管理系统”的设计与实现(源码+数据库+文档+PPT)
基于SpringBoot的“校园台球厅人员与设备管理系统”的设计与实现(源码数据库文档PPT) 开发语言:Java 数据库:MySQL 技术:SpringBoot 工具:IDEA/Ecilpse、Navicat、Maven 系统展示 系统功能结构图 系统首页界面图…...
【Java数据结构】关于栈的操作出栈,压栈,中缀表达式,后缀表达式,逆波兰表达式详解
🔥个人主页:努力学编程’ 🔥内容管理:java数据结构 上一篇文章我们讲过了java数据结构的链表,对于链表我们使用了它的一些基本操作,完成了扑克牌小游戏的操作,如果你感兴趣的话,点…...
wireshark 使用
wireshark介绍 wireshak可以抓取经过主机网卡的所有数据包(包括虚拟机使用的虚拟网卡的数据包)。 环境安装 安装wireshark: https://blog.csdn.net/Eoning/article/details/132141665 安装网络助手工具:https://soft.3dmgame.com/down/213…...
手游刚开服就被攻击怎么办?如何防御DDoS?
开服初期是手游最脆弱的阶段,极易成为DDoS攻击的目标。一旦遭遇攻击,可能导致服务器瘫痪、玩家流失,甚至造成巨大经济损失。本文为开发者提供一套简洁有效的应急与防御方案,帮助快速应对并构建长期防护体系。 一、遭遇攻击的紧急应…...
pam_env.so模块配置解析
在PAM(Pluggable Authentication Modules)配置中, /etc/pam.d/su 文件相关配置含义如下: 配置解析 auth required pam_env.so1. 字段分解 字段值说明模块类型auth认证类模块,负责验证用户身份&am…...
剑指offer20_链表中环的入口节点
链表中环的入口节点 给定一个链表,若其中包含环,则输出环的入口节点。 若其中不包含环,则输出null。 数据范围 节点 val 值取值范围 [ 1 , 1000 ] [1,1000] [1,1000]。 节点 val 值各不相同。 链表长度 [ 0 , 500 ] [0,500] [0,500]。 …...
三体问题详解
从物理学角度,三体问题之所以不稳定,是因为三个天体在万有引力作用下相互作用,形成一个非线性耦合系统。我们可以从牛顿经典力学出发,列出具体的运动方程,并说明为何这个系统本质上是混沌的,无法得到一般解…...
成都鼎讯硬核科技!雷达目标与干扰模拟器,以卓越性能制胜电磁频谱战
在现代战争中,电磁频谱已成为继陆、海、空、天之后的 “第五维战场”,雷达作为电磁频谱领域的关键装备,其干扰与抗干扰能力的较量,直接影响着战争的胜负走向。由成都鼎讯科技匠心打造的雷达目标与干扰模拟器,凭借数字射…...
大数据学习(132)-HIve数据分析
🍋🍋大数据学习🍋🍋 🔥系列专栏: 👑哲学语录: 用力所能及,改变世界。 💖如果觉得博主的文章还不错的话,请点赞👍收藏⭐️留言Ǵ…...
python执行测试用例,allure报乱码且未成功生成报告
allure执行测试用例时显示乱码:‘allure’ �����ڲ����ⲿ���Ҳ���ǿ�&am…...
GitFlow 工作模式(详解)
今天再学项目的过程中遇到使用gitflow模式管理代码,因此进行学习并且发布关于gitflow的一些思考 Git与GitFlow模式 我们在写代码的时候通常会进行网上保存,无论是github还是gittee,都是一种基于git去保存代码的形式,这样保存代码…...
省略号和可变参数模板
本文主要介绍如何展开可变参数的参数包 1.C语言的va_list展开可变参数 #include <iostream> #include <cstdarg>void printNumbers(int count, ...) {// 声明va_list类型的变量va_list args;// 使用va_start将可变参数写入变量argsva_start(args, count);for (in…...
论文阅读:LLM4Drive: A Survey of Large Language Models for Autonomous Driving
地址:LLM4Drive: A Survey of Large Language Models for Autonomous Driving 摘要翻译 自动驾驶技术作为推动交通和城市出行变革的催化剂,正从基于规则的系统向数据驱动策略转变。传统的模块化系统受限于级联模块间的累积误差和缺乏灵活性的预设规则。…...
