蓝桥杯算法基础(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…...
Cursor实现用excel数据填充word模版的方法
cursor主页:https://www.cursor.com/ 任务目标:把excel格式的数据里的单元格,按照某一个固定模版填充到word中 文章目录 注意事项逐步生成程序1. 确定格式2. 调试程序 注意事项 直接给一个excel文件和最终呈现的word文件的示例,…...

CentOS下的分布式内存计算Spark环境部署
一、Spark 核心架构与应用场景 1.1 分布式计算引擎的核心优势 Spark 是基于内存的分布式计算框架,相比 MapReduce 具有以下核心优势: 内存计算:数据可常驻内存,迭代计算性能提升 10-100 倍(文档段落:3-79…...
【RockeMQ】第2节|RocketMQ快速实战以及核⼼概念详解(二)
升级Dledger高可用集群 一、主从架构的不足与Dledger的定位 主从架构缺陷 数据备份依赖Slave节点,但无自动故障转移能力,Master宕机后需人工切换,期间消息可能无法读取。Slave仅存储数据,无法主动升级为Master响应请求ÿ…...

第 86 场周赛:矩阵中的幻方、钥匙和房间、将数组拆分成斐波那契序列、猜猜这个单词
Q1、[中等] 矩阵中的幻方 1、题目描述 3 x 3 的幻方是一个填充有 从 1 到 9 的不同数字的 3 x 3 矩阵,其中每行,每列以及两条对角线上的各数之和都相等。 给定一个由整数组成的row x col 的 grid,其中有多少个 3 3 的 “幻方” 子矩阵&am…...

【JavaWeb】Docker项目部署
引言 之前学习了Linux操作系统的常见命令,在Linux上安装软件,以及如何在Linux上部署一个单体项目,大多数同学都会有相同的感受,那就是麻烦。 核心体现在三点: 命令太多了,记不住 软件安装包名字复杂&…...

接口自动化测试:HttpRunner基础
相关文档 HttpRunner V3.x中文文档 HttpRunner 用户指南 使用HttpRunner 3.x实现接口自动化测试 HttpRunner介绍 HttpRunner 是一个开源的 API 测试工具,支持 HTTP(S)/HTTP2/WebSocket/RPC 等网络协议,涵盖接口测试、性能测试、数字体验监测等测试类型…...

Linux nano命令的基本使用
参考资料 GNU nanoを使いこなすnano基础 目录 一. 简介二. 文件打开2.1 普通方式打开文件2.2 只读方式打开文件 三. 文件查看3.1 打开文件时,显示行号3.2 翻页查看 四. 文件编辑4.1 Ctrl K 复制 和 Ctrl U 粘贴4.2 Alt/Esc U 撤回 五. 文件保存与退出5.1 Ctrl …...

Golang——6、指针和结构体
指针和结构体 1、指针1.1、指针地址和指针类型1.2、指针取值1.3、new和make 2、结构体2.1、type关键字的使用2.2、结构体的定义和初始化2.3、结构体方法和接收者2.4、给任意类型添加方法2.5、结构体的匿名字段2.6、嵌套结构体2.7、嵌套匿名结构体2.8、结构体的继承 3、结构体与…...
【Android】Android 开发 ADB 常用指令
查看当前连接的设备 adb devices 连接设备 adb connect 设备IP 断开已连接的设备 adb disconnect 设备IP 安装应用 adb install 安装包的路径 卸载应用 adb uninstall 应用包名 查看已安装的应用包名 adb shell pm list packages 查看已安装的第三方应用包名 adb shell pm list…...

MySQL:分区的基本使用
目录 一、什么是分区二、有什么作用三、分类四、创建分区五、删除分区 一、什么是分区 MySQL 分区(Partitioning)是一种将单张表的数据逻辑上拆分成多个物理部分的技术。这些物理部分(分区)可以独立存储、管理和优化,…...