首页 > 编程语言 >搜索算法合集 - By DijkstraPhoenix

搜索算法合集 - By DijkstraPhoenix

时间:2024-10-06 16:33:24浏览次数:6  
标签:标记 int dfs vis continue 搜索算法 DijkstraPhoenix maze 合集

搜索算法合集

By DijkstraPhoenix

深度优先搜索 (DFS)

引入

如果现在有一个迷宫,如何走路径最短?

方法

走迷宫最简单粗暴的方法式什么呢?当然是把所有路都走一遍啦!

如果是手动计算的话,可能会把你手指累得抽筋,但电脑不会,电脑具有强大的算力,这种暴力的事情当然是交给电脑做啦。

深搜的本质:一条路走到底,走到死胡同再往回走,回到上一个岔口继续走,直到找到正确的路

实际上,任何一条路都可以看做是一个只有一个岔口的分岔路,所以不需要把路和岔口分开计算。

那么刚才的例子应该是这么走(数字代表第几次尝试)实际上岔口走的顺序是任意的,方法不唯一。

概念:从死胡同返回的步骤叫做回溯

由于深搜不能保证第一次找到的路径为最短路径,所以需要统计所有路线

深搜一般使用递归实现,走过的每个位置都要打上标记,同一条路不能再走一遍

主算法代码:

int maze[MAXN][MAXN];//存储迷宫 0表示当前节点可以走,1表示不能走
bool vis[MAXN][MAXN];//打标记
const int dx[]={1,0,-1,0};
const int dy[]={0,1,0,-1};//位移数组,分别对应 上右下左(如果是八向移动的话要改成对应的)
int n,m,stx,sty,edx,edy;//地图长宽以及起点和终点的坐标
int ans=0x7f7f7f7f;//最短距离,要初始化为极大值

void dfs(int x,int y,int z)//x和y是当前位置的坐标,z是走过的步数
{
    if(x==edx&&y==edy)//到了终点
    {
        ans=min(ans,z);//更新答案(如果答案还是极大值,说明无法到达终点)
        return;
    }
    vis[x][y]=true;//打标记
    for(int i=0;i<4;i++)//枚举四个方向
    {
        int nx=x+dx[i],ny=y+dy[i];//下一个应该走到的位置
        if(nx<1||nx>n||ny<1||ny>m)continue;//不能走出地图(这个要写在灵魂拷问的最前面,否则访问数组要越界)
        if(maze[nx][ny]==1)continue;//不能卡墙里
        if(vis[nx][ny])continue;//不能走你走过的路
        dfs(nx,ny,z+1);//走到下一个节点
    }
    vis[x][y]=false;//重点!回溯时要清除标记!
}

例题

迷宫

洛谷 P1605

解法见上文

#include<iostream>
#include<cstring>
using namespace std;
int num=0;
int n,m,t,edx,edy,stx,sty;
int maze[10][10];
int vis[10][10];
int dx[]={0,1,0,-1};
int dy[]={1,0,-1,0};
void dfs(int x,int y)
{

    vis[x][y]=1;
    if(x==edx&&y==edy)
    {
        num++;
        vis[x][y]=0;
        return;
    }
    for(int i=0;i<4;i++)
    {
        int nx=x+dx[i];
        int ny=y+dy[i];
        if(nx<1||nx>n||ny<1||ny>m)continue;
        if(maze[nx][ny]==1)continue;
        if(vis[nx][ny]==1)continue;
        dfs(nx,ny);
    }
    vis[x][y]=0;
}
int main(void)
{
    int xjx,xjy;
    memset(vis,0,sizeof(vis));
    memset(maze,0,sizeof(maze));
    cin>>n>>m>>t;
    cin>>stx>>sty>>edx>>edy;
    for(int i=1;i<=t;i++)
    {
        cin>>xjx>>xjy;
        maze[xjx][xjy]=1;
    }
    vis[stx][sty]=1;
    dfs(stx,sty);
    cout<<num;
    return 0;
}

八皇后问题

洛谷 P1219

本题的每一步都决定一个皇后的位置,由输出格式就可以看出,我们可以按每一列的顺序计算。一个皇后会独占一行、一列、两斜线,因为是按列计算的,不需要给列打标记,则需要 3 个标记数组。

(其实可以看一下洛谷上的题解)

#include<bits/stdc++.h>
using namespace std;
bool vis[15],vis1[35],vis2[35];
int n;
int nod[15];
int sum=0;
void dfs(int k)
{
    if(k>n)
    {
        sum++;
        if(sum<=3)//前3个要输出方案
        {
            for(int i=1;i<=n;i++)cout<<nod[i]<<" ";
            cout<<endl;
        }
        return;
    }
    for(int i=1;i<=n;i++)
    {
        if(vis[i])continue;
        if(vis1[i+k-1])continue;
        if(vis2[i-k+13])continue;
        vis[i]=true;
        vis1[i+k-1]=true;
        vis2[i-k+13]=true;//可以手动模拟一下行列坐标和斜坐标的关系,加13是防止计算出负数
        nod[k]=i;//保存方案
        dfs(k+1);
        vis[i]=false;
        vis1[i+k-1]=false;
        vis2[i-k+13]=false;
    }
}
int main(void)
{
    cin>>n;
    dfs(1);
    cout<<sum;
    return 0;
}

全排列问题

洛谷 P1706

按照题意模拟搜索即可

#include<iostream>
#include<cstdio>
using namespace std;
int n,a[1000],vis[1000];
void dfs(int step)
{
	if(step==n+1)
	{
		for(int i=1;i<=n;i++)
		{
			printf("%5d",a[i]);//题目要求格式化输出
		}
		cout<<endl;
	}
	for(int i=1;i<=n;i++)
	{
		if(vis[i]==1)continue;
		a[step]=i;
		vis[i]=1;
		dfs(step+1);
		vis[i]=0;
	}
}
int main(void)
{
	cin>>n;
	dfs(1);
	return 0;
}

一些建议练习的题

求细胞数量
提示:联通块问题,不要清除标记,从每个未标记且是细胞的块出发,将整个块打上标记

小猫爬山

选数

单词接龙

--没写完呢--

标签:标记,int,dfs,vis,continue,搜索算法,DijkstraPhoenix,maze,合集
From: https://www.cnblogs.com/dijkstraphoenix/p/18449170

相关文章

  • 大模型~合集7
    我自己的原文哦~  https://blog.51cto.com/whaosoft/11566532# 语言模型是否会规划未来tokenTransformer本可以深谋远虑,但就是不做,语言模型是否会规划未来token?这篇论文给你答案。「别让YannLeCun看见了。」YannLeCun表示太迟了,他已经看到了。今天要介绍的这篇......
  • Living-Dream 系列笔记 第80期(国庆集训合集)
    IDDFS使用场景:搜索树非常大而答案的深度较浅,一般在\(20\)以内,且dfs会TLE,bfs会MLE。算法原理:以dfs的形式搜索;设定搜索的深度限制\(dep\);dfs深度不能超过\(dep\),且要恰好遍历所有\(dep\)的状态;若在\(dep\)层没有找到答案,\(dep+1\todep\),重新DFS......
  • 小米13T Pro系统合集:性能与摄影的极致融合,值得你升级的系统ROM
    小米13TPro是一款性能卓越、设计精美的旗舰机型,具备多项领先配置,且在与前一代产品及友商机型的对比中优势明显,值得深入探讨。性能提升小米13TPro搭载了最新的天玑9200+处理器,相较于前一代(小米12TPro)的骁龙8+Gen1,在性能和能效表现上均有显著提升。天玑9200+的A......
  • 51c嵌入式~电路~合集7
    一、借助示波器看以太网传输机制本文以双绞线以太网为分析对象,以混合信号示波器为分析工具,深入探秘了两类常见的双绞线以太网的编码,且实地查看并验证了以太网在物理层的信号传输情况。最后,通过一个实战例子对比了实际网络中软件接收的数据和示波器捕获信号之间的一致性。本文打通软......
  • 51c自动驾驶~合集32
    #速度场如何在复杂城市场景规划中大显身手香港科技大学新作本篇文章提出了一种局部地图表示方法(即速度场)来解决无法为所有场景设计通用规划规则的问题。此外,本文开发了一种高效的迭代轨迹优化器,其与速度场无缝兼容,实现了训练和推理过程。实验结果表明,本文方法为提高自动驾驶系统的......
  • AutoJsPro项目脚本合集(附带全套源码,线程不会的看过来)
    话不多说,直接上代码"ui";letKeepAliveService={/**开启*/start:function(idStr,nameStr){try{idStr=idStr||"";letchannel_id=idStr+".foreground";letchannel_name=nameStr+"前台服务通知&q......
  • ChatGPT国内中文版镜像网站整理合集(2024/9/28)
    一、GPT中文镜像站① yixiaai.com 支持GPT4、4o以及o1,支持MJ绘画② chat.lify.vip 支持通用全模型,支持文件读取、插件、绘画、AIPPT③ AIChat 支持GPT3.5/4,4o以及MJ绘画1.什么是镜像站镜像站(MirrorSite)是指通过复制原始网站内容和结构,创建的备用网站。其主要目的......
  • ChatGPT国内中文版镜像网站整理合集(2024/9/30)
    一、GPT中文镜像站① yixiaai.com 支持GPT4、4o以及o1,支持MJ绘画② chat.lify.vip 支持通用全模型,支持文件读取、插件、绘画、AIPPT③ AIChat 支持GPT3.5/4,4o以及MJ绘画1.什么是镜像站镜像站(MirrorSite)是指通过复制原始网站内容和结构,创建的备用网站。其主要目的......
  • .NET|--WPF|--笔记合集|--依赖项属性|--5.附加属性
    前言附加属性是一个ExtensibleApplicationMarkupLanguage(XAML)概念。附加属性允许为派生自DependencyObject的任何XAML元素设置额外的属性/值对,即使该元素未在其对象模型中定义这些额外的属性。额外的属性可进行全局访问。附加属性通常定义为没有常规属性包装......
  • 深度DFS 和 广度BFS搜索算法学习
    深度DFS和广度BFS搜索算法学习 目录广度优先的动态图深度优先的动态图广度和深度的具体步骤深度和广度的应用场景 图的两种遍历方式:深度优先遍历(DFS——DepthFirstSearch)广度优先遍历(BFS——BreathFirstSearch)图的遍历算法里,处理临时数据,依赖两个抽象......