DFS——连通性和搜索顺序

dfs的搜索是基于栈,但一般可以用用递归实现,实际上用的是系统栈。有内部搜索和外部搜索两种,内部搜索是在图的内部,内部搜索一般基于连通性,从一个点转移到另一个点,或者判断是否连通之类的问题,只需要标记避免重复访问即可,不需要还原状态,而外部搜索则是将一张图视为一种状态,每一个状态延伸得到新的状态,要保证每个状态往外延伸时都是相同的,那么就需要还原状态。

搜索顺序也很重要,我们要找到合适的搜索顺序保证不漏的搜出每一种情况,重复当然没什么问题。

另外,同宽搜相比,深搜的代码会简单一些,但是却有爆栈的风险,递归层数比较高的时候需要注意。

1112. 迷宫(活动 - AcWing)

思路:本质上就是判断能不能从这点到达另一点,那么就是连通性问题,深搜宽搜都可以,这里我们用深搜来实现。

#include<bits/stdc++.h>
using namespace std;
int n;
char s[120][120];
int sx,sy,ex,ey;
int dx[]={0,0,1,-1};
int dy[]={1,-1,0,0};
int st[120][120];
int dfs(int x,int y)
{if(s[x][y]=='#') return 0; if(x==ex&&y==ey) return 1;st[x][y]=1;for(int i=0;i<4;i++){int nx=x+dx[i],ny=y+dy[i];if(nx<0||nx>=n||ny<0||ny>=n) continue;if(st[nx][ny]) continue;if(dfs(nx,ny)) return 1;}return 0;
}
int main()
{int t;scanf("%d",&t);while(t--){scanf("%d",&n);for(int i=0;i<n;i++) scanf("%s",s[i]);scanf("%d%d%d%d",&sx,&sy,&ex,&ey);if(dfs(sx,sy)) cout<<"YES"<<endl;else cout<<"NO"<<endl;memset(st,0,sizeof st);}
}

1113. 红与黑(1113. 红与黑 - AcWing题库)

思路:实际上就是统计一个连通块内有多少个元素。

#include<bits/stdc++.h>
using namespace std;
char g[30][30];
int n,m;
int cnt;
int dx[]={0,0,1,-1};
int dy[]={1,-1,0,0};
int st[30][30];
void dfs(int x,int y)
{st[x][y]=1;cnt++;for(int i=0;i<4;i++){int nx=x+dx[i],ny=y+dy[i];if(nx<0||nx>=n||ny<0||ny>=m) continue;if(st[nx][ny])continue;if(g[nx][ny]=='#') continue;dfs(nx,ny);}
}
int main()
{while(scanf("%d%d",&m,&n)){if(!n&&!m) break;for(int i=0;i<n;i++) scanf("%s",g[i]);for(int i=0;i<n;i++)for(int j=0;j<m;j++)if(g[i][j]=='@'){cnt=0;dfs(i,j);cout<<cnt<<endl;break;}memset(st,0,sizeof st);}
}

 1116. 马走日(活动 - AcWing)

思路:这题看似是说在棋盘内部移动,但实际上每次统计一个结果的前提是整个棋盘都被遍历,而且每一步移动有八个选择(理想情况),八个选择各自代表不同的状态,所以我们需要还原状态,只用在最后递归到所有节点都访问过时,记录一下即可。

#include<bits/stdc++.h>
using namespace std;
int n,m;
int st[10][10];
int ans;
int dx[]={1,1,-1,-1,2,2,-2,-2};
int dy[]={2,-2,2,-2,1,-1,1,-1};
void dfs(int x,int y,int k)
{if(k==n*m) {ans++;return;}st[x][y]=1;for(int i=0;i<8;i++){int nx=x+dx[i],ny=y+dy[i];if(nx<0||nx>=n||ny<0||ny>=m) continue;if(st[nx][ny]) continue;dfs(nx,ny,k+1);}st[x][y]=0;
}
int main()
{int t;scanf("%d",&t);while(t--){int x,y;scanf("%d%d%d%d",&n,&m,&x,&y);ans=0;dfs(x,y,1);cout<<ans<<endl;}
}

ps:特殊情况单独判返回的时候一定要注意状态有没有请干净。

1117. 单词接龙(活动 - AcWing)

思路:这里首先要想搜索,我们需要建立单词与单词之间的关系,准确来说我们需要知道哪些单词可以接在哪些单词的后面,它们的重合长度是多少,这里的重合长度一定要越小越好,因为我们可以任意选择重合长度。

那么预处理完之后,直接深搜记录最大值即可。

另外要注意每个单词只能用两次,那么需要记录一下当前单词已经用了几次了,我们可以用下标来实现。

#include<bits/stdc++.h>
using namespace std;
int n;
string s[30];
int used[30];
int g[30][30];
int mx;
void dfs(string r,int k)
{if(used[k]==2) return;used[k]++;for(int i=0;i<n;i++){if(g[k][i]&&used[i]<2){string tmp=r+s[i].substr(g[k][i]);//cout<<r<<" "<<s[i].substr(g[k][i])<<" "<<g[k][i]<<endl;mx=max(mx,(int)tmp.size());dfs(r+s[i].substr(g[k][i]),i);}}used[k]--;
}
int main()
{scanf("%d",&n);for(int i=0;i<n;i++) cin>>s[i];for(int i=0;i<n;i++){for(int j=0;j<n;j++){for(int k=1;k<min(s[i].size(),s[j].size());k++){if(s[i].substr(s[i].size()-k,k)==s[j].substr(0,k)){g[i][j]=k;break;}}//printf("%d ",g[i][j]);}//printf("\n");}char c;cin>>c;mx=0;for(int i=0;i<n;i++){if(s[i][0]==c){mx=max(mx,(int)s[i].size());dfs(s[i],i);}}cout<<mx;
}

 1118. 分成互质组(活动 - AcWing)

思路:如果我们将第一个数放在第一组,那么遍历后面的数,如果不与第一组中的数互质,那么就可以放进这一组,否则就只能新开一组,如此递归来实现,就可保证将所有的数都分好组,同时是分组最少的。

另外由于放进同一个组内的顺序无所谓,所以当不用新开一个组的时候,遍历下一层的时候,直接从后一个元素开始遍历,否则,如果新开组,那么就要从开头开始遍历。因为是按顺序遍历的,所以当前元素被遍历前,它之前的元素与这一组的关系都已经判断过了,所以如果不新开组那么就没必要再往前看。

#include<bits/stdc++.h>
using namespace std;
int n;
int a[20];
int g[20][20];
int ans=10;
int st[20];
int gcd(int a,int b)
{return b?gcd(b,a%b):a;
}
int check(int u,int g[],int cn)
{for(int i=0;i<cn;i++){if(gcd(a[u],a[g[i]])>1) return 0; }return 1;
}
void dfs(int u,int c,int k,int cn)//u是此时从哪个点开始判断,c是当前处在第几个组,k是已经分配几个点了,cn当前组中有多少个元素
{if(c>=ans) return;if(k==n){ans =min(ans,c);return;}int flag=1;for(int i=u;i<n;i++){if(!st[i]&&check(i,g[c],cn))//一个点都不能放入了再新开{st[i]=1;g[c][cn]=i;dfs(u+1,c,k+1,cn+1);st[i]=0;flag=0;}}if(flag) dfs(0,c+1,k,0);
}
int main()
{scanf("%d",&n);for(int i=0;i<n;i++) scanf("%d",&a[i]);dfs(0,1,0,0);cout<<ans;
}

 

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

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

相关文章

[Python] opencv - 什么是直方图?如何绘制图像的直方图?

什么是直方图&#xff1f; 直方图是一种统计图&#xff0c;用于展示数据的分布情况。它将数据按照一定的区间或者组进行划分&#xff0c;然后计算在每个区间或组内的数据频数或频率&#xff08;即数据出现的次数或占比&#xff09;&#xff0c;然后用矩形或者柱形图的形式将这…

C++学习Day03之构造函数和析构函数

目录 一、程序及输出1.1 构造函数1.2 析构函数1.3 构造和析构必须要声明在全局作用域 二、分析与总结 一、程序及输出 1.1 构造函数 构造函数 没有返回值 不用写void 函数名 与 类名相同 可以有参数 &#xff0c;可以发生重载 构造函数 由编译器自动调用一次 无须手动调用 创建…

C语言——Q/编译和链接

目录 一、翻译环境和运⾏环境 二、翻译环境 1、预处理&#xff08;预编译&#xff09; 2、编译 2.2.1 词法分析&#xff1a; 2.2.2 语法分析 2.2.3 语义分析 3、汇编 4、链接 三、运行环境 一、翻译环境和运行环境 在ANSI C 的任何⼀种实现中&#xff0c;存在两个不…

CentOS7局域网内搭建本地yum源

CentOS7.6 局域网内搭建本地yum源 一、背景 客户机房服务器无法直连公网&#xff0c;远程通过堡垒机部署环境&#xff0c;因为机器比较多&#xff0c;最终选择通过安装自定义yum源进行部署。以下为自己部署yum源过程&#xff0c;以备后续使用。 二、准备yum源Packages 网上…

【刷题题解】最长回文子序列

给你一个字符串 s &#xff0c;找出其中最长的回文子序列&#xff0c;并返回该序列的长度。 子序列定义为&#xff1a;不改变剩余字符顺序的情况下&#xff0c;删除某些字符或者不删除任何字符形成的一个序列 这道题&#xff0c;一眼动态规划&#xff0c;但是即使动起来也规划…

突破编程_C++_面试(基础知识(5))

面试题9&#xff1a;什么是内存地址 内存地址是指计算机内存中存储变量或对象的地址。内存空间大小就是寻址能力&#xff0c;即能访问到多少个地址&#xff0c;比如 32 位机器内存空间大小就是 2^32 4294967296&#xff0c;也就是 4 GB 。每个变量或对象在内存中都有一个唯一…

python_蓝桥杯刷题记录_笔记_全AC代码_入门3

前言 记录我的解法以及笔记思路&#xff0c;谢谢观看。 题单目录 1.P2141 [NOIP2014 普及组] 珠心算测验 2.P1567 统计天数 3.P1055 [NOIP2008 普及组] ISBN 号码 4.P1200 [USACO1.1] 你的飞碟在这儿 Your Ride Is Here 5.P1308 [NOIP2011 普及组] 统计单词数 6.P1047 […

2024.2.3日总结(animate.css)

animate.css animate.css是一个动画库&#xff0c;可以方便快速的制作出常见的动画效果&#xff0c;很适合强调&#xff0c;主页&#xff0c;滑块和注意力引导提示。 它预设了弹跳&#xff08;bounce&#xff09;&#xff0c;摇摆&#xff08;swing&#xff09;&#xff0c;颤…

CF1538 补题报告

CF1538补题报告&#xff08;A.B.C.D.F.G.&#xff09; Codeforces Round 725 (Div. 3) A. Stone Game A. 石头游戏 题意 给定一个序列&#xff0c;每次只能删除最左边或最右边的元素&#xff0c;求出删除最大和最小值需要多少次删除操作。 思路 找到最大值和最小值所在的…

C#创建lnk快捷方式

1&#xff0c;引用Com组件:Windows Script Host Object Model。 2&#xff0c;获取开始目录路径、桌面路径&#xff0c;并创建相应文件夹。 //获取当前开始目录,桌面//当前值为:C:\Users\admin\AppData\Roaming\Microsoft\Windows\Start Menu//实际需要的路径是:C:\Users\adm…

深度学习之循环神经网络进阶

这一讲我们学习如何实现一个循环神经网络的分类器&#xff1a; 我们要解决的问题是名字分类&#xff0c;我们根据名字找到其对应的国家。 上一讲我们介绍了循环神经网络。 我们在处理自然语言的时候我们通常是以上这种方式&#xff0c;我们在处理单词的时候&#xff0c;通常…

一文彻底搞懂MySQL基础:B树和B+树的区别(简洁版)

文章目录 1. 节点结构2. 插入和删除3. 查询4. 性能5. 适用场景6.关于 B树和 B树的常见问题6.1. B树和B树的区别是什么&#xff1f;6.2. 什么情况下应该使用 B树&#xff1f;6.3. 什么情况下应该使用 B树&#xff1f; B树和B树都是多路搜索树&#xff0c;它们都用于数据库索引中…

QT自用,勿点

自己有接近2年的前端经验&#xff08;html,js,jq,vue之类的&#xff09;&#xff0c;但是一直对QT不是很熟悉&#xff0c;之前零散的学了一些&#xff0c;但是平时不怎么做界面&#xff0c;这几天系统的学一下。 1.7 创建第一个Qt项目_哔哩哔哩_bilibili 文档: *Qt中的信号槽…

命令注入漏洞原理以及修复方法

漏洞名称 &#xff1a;命令注入 漏洞描述&#xff1a;Command Injection&#xff0c;即命令注入攻击&#xff0c;是指由于Web应用程序对用户提交的数据过滤 不严格&#xff0c;导致黑客可以通过构造特殊命令字符串的方式&#xff0c;将数据提交至Web应用程序中&#xff0c;并利…

一文讲明Jetpack中的图片组件

Jetpack Compose系列(5) - 图片组件 Jetpack Compose中的常用图片组件有两个&#xff1a;Icon和Image。从命名上就不难看出这两个组件在内容呈现上就是负责图形和图片相关。 需要说明的是&#xff0c;Compose获取资源方式有四种&#xff1a; 文本 -> stringResource(R.s…

C# 从“byte[]”转换为“BitmapImage”

要从字节数组 (byte[]) 转换为 System.Windows.Media.Imaging.BitmapImage&#xff0c;你需要使用一个内存流 (MemoryStream) 来读取字节数组&#xff0c;并利用这个流来初始化 BitmapImage。以下是如何执行这一转换的详细步骤和代码示例&#xff1a; 将字节数组转换为 Bitmap…

比特币ETF广告战大爆发!

作者&#xff1a;秦晋 贝莱德主动发起广告攻势。 2月1日&#xff0c;据外媒Cryptoslate报道&#xff0c;贝莱德在提交给美国SEC的一份文件中显示&#xff0c;其提出一项在建筑物侧面投影比特币ETF广告计划。 据介绍&#xff0c;广告内容为&#xff1a;「IBIT」信号是一个以迈阿…

【Qt+MSVC2017_64bit +Cmake新建项目编译出错】

项目场景&#xff1a; 提示&#xff1a;这里简述项目相关背景&#xff1a; 项目新电脑环境配置 QtMSVC2017_64bit Cmake新建项目编译出错 问题描述 提示&#xff1a;这里描述项目中遇到的问题&#xff1a; QtMSVC2017_64bit Cmake新建项目编译出错 Running C:\Program Fil…

【数据分享】1米分辨率土地覆盖数据集SinoLC-1

数据链接 SinoLC-1: the first 1-meter resolution national-scale land-cover map of China created with the deep learning framework and open-access data (Update data: August, 2023) (zenodo.org)https://zenodo.org/records/8214467 数据分享 数据分享到了公众号&…

Android studio改代码运行不生效

Android studio改代码后运行不生效&#xff0c;尝试卸载apk后&#xff0c;运行能生效&#xff0c;后面尝试手动通过adb命令安装生成的apk能生效。 studio 版本 解决方案&#xff1a; 在File->Settings->Build, Execution, Deployment&#xff0c;找到Android Configura…