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.hqwc.cn/news/452355.html

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

相关文章

赎金信[简单]

优质博文&#xff1a;IT-BLOG-CN 一、题目 给你两个字符串&#xff1a;ransomNote和magazine&#xff0c;判断ransomNote能不能由magazine里面的字符构成。如果可以&#xff0c;返回true&#xff1b;否则返回false。magazine中的每个字符只能在ransomNote中使用一次。 示例 …

使用wda框架实现IOS自动化测试详解

目录 1、weditor元素定位工具 1.1、weditor的安装和使用 2、wda iOS自动化框架 2.1、wda概述 2.2、wda安装 2.3、wda的使用 2.3.1、全局配置 2.3.2、创建客户端 2.3.3、APP相关操作 1、启动APP 2、关闭APP 3、获取APP状态信息 4、获取当前APP的运行信息 2.3.4、设…

BP图片降噪MATLAB代码

BP(Back Propagation)神经网络是一种常用的深度学习模型,可以用于图像降噪。主要步骤包括: 构建BP神经网络模型。包括输入层、隐藏层和输出层。输入层大小与图像大小相同,输出层大小也与输入图像大小相同。隐藏层根据图像复杂度设定。 准备训练数据。使用干净图像作为输入,加…

《计算机网络简易速速上手小册》第10章:未来网络技术趋势(2024 最新版)

文章目录 10.1 边缘计算与网络设计 - 未来网络的速度与激情10.1.1 基础知识10.1.2 重点案例&#xff1a;使用 Python 实现边缘计算的实时视频分析准备工作Python 脚本示例 10.1.3 拓展案例1&#xff1a;智能交通系统Python 脚本示例 - 边缘计算设备上的交通流量分析 10.1.4 拓展…

Qt之使用Qt内置图标

一效果 二.原理 Qt内置图标封装在QStyle中,共七十多个图标,可以直接拿来用,能应付不少简单程序需求,不用自己去找图标并添加到资源文件了。 下面是内置图标的枚举定义: enum StandardPixmap {SP_TitleBarMenuButton,SP_TitleBarMinButton,SP_TitleBarMaxButton,SP_T…

如何实现冻干机和产品全生命周期的验证和监测?

为什么冻干需要工艺优化和合规性 冻干是制药和生物技术产品的关键工艺&#xff0c;需要精确控制关键的温度和压力参数。通过遵守 GMP 和 FDA 合规性等监管准则&#xff0c;您可以生产出更高质量的产品&#xff0c;避免不必要的浪费&#xff0c;并缩短产品上市时间。 要想在冻干…

ArcGIS Pro 按照字段进行融合或拆分

ArcGIS Pro 按字段融合 在ArcGIS Pro中&#xff0c;通过使用“融合”工具可以轻松地合并具有相同字段的图层。 步骤一&#xff1a;打开ArcGIS Pro 启动ArcGIS Pro应用程序&#xff0c;确保您已经登录并打开您的项目。 步骤二&#xff1a;添加图层 将包含相同字段的图层添加到…

简易计算器的制作(函数指针数组的实践)

个人主页&#xff08;找往期文章&#xff09;&#xff1a;我要学编程(ಥ_ಥ)-CSDN博客 前期思路&#xff08;菜单的制作等&#xff09;&#xff1a;利用C语言的分支循环少量的函数知识写一个猜数字的小游戏-CSDN博客 计算器的制作其实与游戏没有很大的区别。 #include <st…

STL常用容器—list容器(链表)

STL常用容器—list容器&#xff08;链表&#xff09; 一、list容器基本概念二、list容器基本操作与常用方法1. list构造函数2. ☆list 插入和删除3. list 获取头尾数据4. list 大小操作5. list赋值和交换6. list 反转和排序 三、排序案例 参考博文1: &#xff1c;C&#xff1e;…

GLIP:零样本学习 + 目标检测 + 视觉语言大模型

GLIP 核心思想GLIP 对比 BLIP、BLIP-2、CLIP 主要问题: 如何构建一个能够在不同任务和领域中以零样本或少样本方式无缝迁移的预训练模型&#xff1f;统一的短语定位损失语言意识的深度融合预训练数据类型的结合语义丰富数据的扩展零样本和少样本迁移学习 效果 论文&#xff1a;…

React Native

学习目标 解决以下问题: 1.什么是 React Native &#xff1f;为什么它的名字中有 “Native” 字样&#xff1f; 2.为什么 React Native 如此之酷&#xff1f; 3.我们可以分别使用 React Native 和 React 来开发什么&#xff1f; 4.为什么会出现 ReactDOM &#xff1f;它是做什…

Leetcode刷题笔记题解(C++):1863. 找出所有子集的异或总和再求和

思路如下&#xff1a;递归思路&#xff0c;依次遍历数组中的数&#xff0c;当前数要不要选择像二叉树一样去遍历如下图所示 0 0 &#xff08;选5&#xff09; 5&#xff08;不选5&#xff09; 0 1 0 1 0 6 …