DFS BFS

news2025/6/30 8:47:39

用DFS和BFS分别实现

//这边给出DFS的模版
void dfs(int x,int y)
{
	//判断是否到达终点(只有给出结束点的时候需要) 
	if (x == ex && y == ey) {
        if (min_steps > step) {
            min_steps = step;
        }
        return;
    }
	//给出移动方向
	int move[4][2] = {{0, 1}, {0, -1}, {1, 0}, {-1, 0}};
	//以当前的点为基础,开始搜索,搜索的路线为右遇到障碍物或者边界变成向下...... 
	for (int i = 0; i < 4; ++i) {
        int tx = x + move[i][0], ty = y + move[i][1];
        if (tx < 0 || tx >= m || ty < 0 || ty >= n) continue;
        if (a[tx][ty] == 0 && v[tx][ty] == 0) {
            v[tx][ty] = 1;//走过的点打上标记,防止再走一遍 
            dfs(tx, ty, step + 1);
            v[tx][ty] = 0;//由于回溯的需要,需要接触标记,找下一条路径 
        }
    }
    return;	
} 

以下是完整的DFS代码

#include<bits/stdc++.h>
#define itn int
using namespace std;
int sx, sy, ex, ey;
int min_steps = 1000000;
int a[100][100];
int v[100][100];
int m, n;
void dfs(int x, int y, int step) {
    int move[4][2] = {{0, 1}, {0, -1}, {1, 0}, {-1, 0}};
    if (x == ex && y == ey) {
        if (min_steps > step) {
            min_steps = step;
        }
        return;
    }
    for (int i = 0; i < 4; ++i) {
        int tx = x + move[i][0], ty = y + move[i][1];
        if (tx < 0 || tx >= m || ty < 0 || ty >= n) continue;
        if (a[tx][ty] == 0 && v[tx][ty] == 0) {
            v[tx][ty] = 1;
            dfs(tx, ty, step + 1);
            v[tx][ty] = 0;
        }
    }
    return;
}
int main() {
    cin >> sx >> sy >> ex >> ey;
    cin >> m >> n;
    for (int i = 0; i < m; ++i) {
        for (int j = 0; j < n; ++j) {
            cin >> a[i][j];
        }
    }
    v[sx][sy] = 1; 
    dfs(sx, sy, 0);  
    cout << "Minimum steps needed: " << min_steps << endl;
    return 0;
}

  BFS部分:

#include<bits/stdc++.h>
#define itn int
using namespace std;
struct Queue{
	int x;
	int y;
	int s;
};
int a[50][50];
int vis[50][50];
int main()
{
	struct Queue queue[2501];
	int sx,sy,ex,ey,n;
	int flag=0;
	cin>>sx>>sy>>ex>>ey>>n;
	for (int i=0;i<n;++i)
	{
		for (int j=0;j<n;++j)
		{
			cin>>a[i][j];
		}
	}
	int tail=0,head=0;
	queue[tail].x=sx,queue[tail].y=sy,queue[tail].s=0;
	int move[4][2] = {{0, 1}, {0, -1}, {1, 0}, {-1, 0}};
	while (head!=tail)
	{
		int x=queue[head].x,y=queue[head].y;
		for (int i=0;i<=3;++i)
		{
			int tx=x+move[i][0],ty=y+move[i][1];
			if (tx==ex && ty==ey)
			{
				flag=1;
				break;
			}
			if (tx<0 || tx>=n || ty<0 || ty<=n) continue;
			if (a[tx][ty]==0 && vis[tx][ty]==0)
			{
				vis[tx][ty]=1;
				queue[tail].x=tx;
				queue[tail].y=ty;
				queue[tail].s=queue[head].s+1;
				tail++;
			}
		}
		if (flag)break;
		head++;
	}
	cout<<queue[tail-1].s;
}

最大岛屿面积https://leetcode.cn/problems/max-area-of-island/description/

给你一个大小为 m x n 的二进制矩阵 grid 。

岛屿 是由一些相邻的 1 (代表土地) 构成的组合,这里的「相邻」要求两个 1 必须在 水平或者竖直的四个方向上 相邻。你可以假设 grid 的四个边缘都被 0(代表水)包围着。

岛屿的面积是岛上值为 1 的单元格的数目。

计算并返回 grid 中最大的岛屿面积。如果没有岛屿,则返回面积为 0 。

示例 1:

输入:grid = [[0,0,1,0,0,0,0,1,0,0,0,0,0],[0,0,0,0,0,0,0,1,1,1,0,0,0],[0,1,1,0,1,0,0,0,0,0,0,0,0],[0,1,0,0,1,1,0,0,1,0,1,0,0],[0,1,0,0,1,1,0,0,1,1,1,0,0],[0,0,0,0,0,0,0,0,0,0,1,0,0],[0,0,0,0,0,0,0,1,1,1,0,0,0],[0,0,0,0,0,0,0,1,1,0,0,0,0]]
输出:6
解释:答案不应该是 11 ,因为岛屿只能包含水平或垂直这四个方向上的 1

示例 2:

输入:grid = [[0,0,0,0,0,0,0,0]]
输出:0

提示:

  • m == grid.length
  • n == grid[i].length
  • 1 <= m, n <= 50
  • grid[i][j] 为 0 或 1

思路:套用搜索模版,找最大的岛屿的面积,只需要便利每一个岛的面积,然后定义一个最大值变量记录最大值就可以。


//BFS
struct Queue{
    int x;
    int y;
};
int vis[55][55];
int maxAreaOfIsland(int** grid, int gridSize, int* gridColSize) {
    struct Queue queue[1000000];
    int line=gridSize;
    int col=*gridColSize;
    int head=0,tail=0;
    int max=0;
    for (int i=0;i<line;++i)
    {
        for (int j=0;j<col;++j)
        {
            if (grid[i][j]==1)
            {
                queue[tail].x=i;
                queue[tail].y=j;
                tail++;
                vis[i][j]=1;
                int sum=1;
                int move[4][2]={{0,1},{1,0},{0,-1},{-1,0}};
                while (head!=tail)
                {
                    int x=queue[head].x,y=queue[head].y;
                    for (int k=0;k<=3;++k)
                    {
                        int tx=x+move[k][0],ty=y+move[k][1];
                        if (tx<0 || tx>=line || ty<0 || ty>=col)continue;
                        if (grid[tx][ty]==1 && vis[tx][ty]==0)
                        {
                            vis[tx][ty]=1;
                            sum++;
                            queue[tail].x=tx;
                            queue[tail].y=ty;
                            tail++;
                        }
                    }
                    head++;
                }
                if (max<sum)max=sum;
            }   
        }
    }
    memset(vis, 0, sizeof(vis));
    return max;
}
//DFS
int line ,col;
int  dfs(int ** grid,int i,int j)
{
    if (i<0 || j>=col || i>=line || j<0 || grid[i][j]==0) return 0 ;
    grid[i][j]=0;
    return 1+dfs(grid,i+1,j)+dfs(grid,i-1,j)+dfs(grid,i,j+1)+dfs(grid,i,j-1);
}
int maxAreaOfIsland(int** grid, int gridSize, int* gridColSize) {
    line=gridSize;
    col=*gridColSize;
    int max=0;
    for (int i=0;i<line;++i)
    {
        for (int j=0;j<col;++j)
        {
            if (grid[i][j]==1)
            {
                int sum=dfs(grid,i,j);
                if (sum>max)max=sum;
            }
        }
    }
    return max;
}

填涂颜色https://www.luogu.com.cn/problem/P1162

题目描述

由数字 00 组成的方阵中,有一任意形状的由数字 11 构成的闭合圈。现要求把闭合圈内的所有空间都填写成 22。例如:6×66×6 的方阵(�=6n=6),涂色前和涂色后的方阵如下:

如果从某个 00 出发,只向上下左右 44 个方向移动且仅经过其他 00 的情况下,无法到达方阵的边界,就认为这个 00 在闭合圈内。闭合圈不一定是环形的,可以是任意形状,但保证闭合圈内的 00 是连通的(两两之间可以相互到达)。

0 0 0 0 0 0
0 0 0 1 1 1
0 1 1 0 0 1
1 1 0 0 0 1
1 0 0 1 0 1
1 1 1 1 1 1
0 0 0 0 0 0
0 0 0 1 1 1
0 1 1 2 2 1
1 1 2 2 2 1
1 2 2 1 2 1
1 1 1 1 1 1

输入格式

每组测试数据第一行一个整数 �(1≤�≤30)n(1≤n≤30)。

接下来 �n 行,由 00 和 11 组成的 �×�n×n 的方阵。

方阵内只有一个闭合圈,圈内至少有一个 00。

输出格式

已经填好数字 22 的完整方阵。

输入输出样例

输入 #1复制

6
0 0 0 0 0 0
0 0 1 1 1 1
0 1 1 0 0 1
1 1 0 0 0 1
1 0 0 0 0 1
1 1 1 1 1 1

输出 #1复制

0 0 0 0 0 0
0 0 1 1 1 1
0 1 1 2 2 1
1 1 2 2 2 1
1 2 2 2 2 1
1 1 1 1 1 1

说明/提示

对于 100%100% 的数据,1≤�≤301≤n≤30。

思路:把1看作墙,遇到就停止搜索下去,但是要注意边界的情况,从边界开始搜索,那么剩下的0的是要变成2的。

#include<bits/stdc++.h>
using namespace std;
int a[35][35],b[35][35];
int n;
void dfs(int x, int y)
{
	int move[4][2]={{0,1},{1,0},{0,-1},{-1,0}};
	for (int i=0;i<=3;++i)
	{
		int tx=x+move[i][0],ty=y+move[i][1];
		if (tx<0 || tx>=n || ty<0 ||ty>=n)continue;
		if (a[tx][ty]==0 && b[tx][ty]==0)
		{
			b[tx][ty]=1;
			dfs(tx,ty);
		}
	}
	return ;
}
int main()
{
	cin>>n;
	for (int i=0;i<n;++i)
	{
		for (int j=0;j<n;++j)
		{
			cin>>a[i][j];
		}
	}
	for (int i=0;i<n;++i)
	{
		if (a[i][0]==0)dfs(i,0);
		if (a[0][i]==0)dfs(0,i);
		if (a[i][n-1]==0)dfs(i,n-1);
		if (a[n-1][i]==0)dfs(n-1,i);
	}
	for (int i=0;i<n;++i)
	{
		for (int j=0;j<n;++j)
		{
			if (b[i][j]==0 && a[i][j]==0)
			{
				a[i][j]=2;
			}
		}
	}
	for (int i=0;i<n;++i)
	{
		for (int j=0;j<n;++j)
		{
			cout<<a[i][j]<<" ";
		}
		cout<<endl;
	}
	return 0;
}

自然数的拆分问题https://www.luogu.com.cn/problem/P2404

题目描述

任何一个大于 11 的自然数 �n,总可以拆分成若干个小于 �n 的自然数之和。现在给你一个自然数 �n,要求你求出 �n 的拆分成一些数字的和。每个拆分后的序列中的数字从小到大排序。然后你需要输出这些序列,其中字典序小的序列需要优先输出。

输入格式

输入:待拆分的自然数 �n。

输出格式

输出:若干数的加法式子。

输入输出样例

输入 #1复制

7

输出 #1复制

1+1+1+1+1+1+1
1+1+1+1+1+2
1+1+1+1+3
1+1+1+2+2
1+1+1+4
1+1+2+3
1+1+5
1+2+2+2
1+2+4
1+3+3
1+6
2+2+3
2+5
3+4

说明/提示

数据保证,2≤�≤82≤n≤8。

思路:主要掌握回溯的用法

#include<bits/stdc++.h>
using namespace std;
int a[35];
int n;
void dfs(int sum, int len, int last) {
    if (sum == n &&len!=1) {
        for (int j = 0; j < len - 1; ++j) {
            cout << a[j] << "+";
        }
        cout << a[len - 1] << endl;
        return;
    }
    for (int i = last; i <= n - sum; ++i) {
        a[len] = i;
        dfs(sum + i, len + 1, i); 
    }
}

int main() {
    cin >> n;
    dfs(0, 0, 1);
    return 0;
}

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

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

相关文章

如何使用python脚本生成redis格式的数据包

用python脚本生成redis格式的数据包 &#xff08;1&#xff09;使用下述网站下载开源的生成gopher协议规则的包的工具 https://github.com/firebroo/sec_tools/tree/master/redis-over-gopher &#xff08;2&#xff09;首先要修改redis.cmd中的内容 flushall config set di…

Linux 运维工具之1Panel

一、1Panel 简介 1Panel 是一个现代化、开源的 Linux 服务器运维管理面板。 特点&#xff1a; 快速建站&#xff1a;深度集成 Wordpress 和 Halo&#xff0c;域名绑定、SSL 证书配置等一键搞定&#xff1b;高效管理&#xff1a;通过 Web 端轻松管理 Linux 服务器&#xff0…

第一讲:BeanFactory和ApplicationContext

BeanFactory和ApplicationContext 什么是BeanFactory 它是ApplicationContext的父接口它才是Spring的核心容器&#xff0c;主要的ApplicationContext实现都组合了它的功能 BeanFactory能做什么? 表面上看BeanFactory的主要方法只有getBean()&#xff0c;实际上控制反转、基…

力扣:63. 不同路径 II(动态规划)

题目&#xff1a; 一个机器人位于一个 m x n 网格的左上角 &#xff08;起始点在下图中标记为 “Start” &#xff09;。 机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角&#xff08;在下图中标记为 “Finish”&#xff09;。 现在考虑网格中有障碍物。那…

【Matlab】基于遗传算法优化BP神经网络 (GA-BP)的数据时序预测

资源下载&#xff1a; https://download.csdn.net/download/vvoennvv/88682033 一&#xff0c;概述 基于遗传算法优化BP神经网络 (GA-BP) 的数据时序预测是一种常用的机器学习方法&#xff0c;用于预测时间序列数据的趋势和未来值。 在使用这种方法之前&#xff0c;需要将时间序…

visual studio + intel Fortran 错误解决

版本&#xff1a;VS2022 intel Fortran 2024.0.2 Package ID: w_oneAPI_2024.0.2.49896 共遇到三个问题。 1.rc.exe not found 2.kernel32.lib 无法打开 3.winres.h 无法打开 我安装时参考的教程&#xff1a;visual studio和intel oneAPI安装与编写fortran程序_visual st…

小巧的Windows Memory Cleaner内存清理工具-释放内存,提升电脑的性能-供大家学习研究参考

软件介绍 Windows Memory Cleaner是一款非常不错的内存清理工具大小仅200KB&#xff0c;这款免费的 RAM 清理器使用本机 Windows 功能来清理内存区域&#xff0c;帮助用户释放内存&#xff0c;提升电脑的性能&#xff0c;有时程序不会释放分配的内存&#xff0c;从而使计算机变…

【Vue2+3入门到实战】(15)VUE路由入门声明式导航的基本使用与详细代码示例

目录 一、声明式导航-导航链接1.需求2.解决方案3.通过router-link自带的两个样式进行高亮4.总结 二、声明式导航-两个类名1.router-link-active2.router-link-exact-active3.在地址栏中输入二级路由查看类名的添加4.总结 三、声明式导航-自定义类名&#xff08;了解&#xff09…

日志高亮 | notepad

高亮显示日志 日志文件无法清晰看到关键问题所在? 看到一堆日志头疼?高亮日志可以清晰展示出日志的 ERROR级等各种等级的问题, 一下浏览出日志关键所在 tailspin 项目地址&#xff1a; https://githubfast.com/bensadeh/tailspin 使用Rust包管理器cargo安装 安装 - Cargo 手…

LeetCode二叉树路径和专题:最大路径和与路径总和计数的策略

目录 437. 路径总和 III 深度优先遍历 前缀和优化 124. 二叉树中的最大路径和 437. 路径总和 III 给定一个二叉树的根节点 root &#xff0c;和一个整数 targetSum &#xff0c;求该二叉树里节点值之和等于 targetSum 的 路径 的数目。 路径 不需要从根节点开始&#xf…

【MYSQL】-函数

&#x1f496;作者&#xff1a;小树苗渴望变成参天大树&#x1f388; &#x1f389;作者宣言&#xff1a;认真写好每一篇博客&#x1f4a4; &#x1f38a;作者gitee:gitee✨ &#x1f49e;作者专栏&#xff1a;C语言,数据结构初阶,Linux,C 动态规划算法&#x1f384; 如 果 你 …

在线智能防雷监控检测系统应用方案

在线智能防雷监控检测系统是一种利用现代信息技术&#xff0c;对防雷设施的运行状态进行实时监测、管理和控制的系统&#xff0c;它可以有效提高防雷保护的安全性、可靠性和智能化程度&#xff0c;降低运维成本和风险&#xff0c;为用户提供全方位的防雷解决方案。 地凯科技在…

Vue常见面试问答

vue响应式数据 vue2 Vue2 的对象数据是通过 Object.defineProperty 对每个属性进行监听&#xff0c;当对属性进行读取的时候&#xff0c;就会触发 getter&#xff0c;对属性进行设置的时候&#xff0c;就会触发 setter。 /** * 这里的函数 defineReactive 用来对 Object.def…

2023.12.28 关于 Redis 数据类型 List 内部编码、应用场景

目录 List 编码方式 早期版本 现今版本 List 实际应用 多表之间的关联关系 消息队列 频道&#xff08;多列表&#xff09;消息队列 微博 Timeline 栈 & 队列 List 编码方式 早期版本 早期版本 List 类型的内部编码方式有两种 ziplist&#xff08;压缩列表&#xf…

论文阅读<Contrastive Learning-based Robust Object Detection under Smoky Conditions>

论文链接&#xff1a;https://openaccess.thecvf.com/content/CVPR2022W/UG2/papers/Wu_Contrastive_Learning-Based_Robust_Object_Detection_Under_Smoky_Conditions_CVPRW_2022_paper.pdf Abstract 目标检测是指有效地找出图像中感兴趣的目标&#xff0c;然后准确地确定它们…

ssrf之gopher协议的使用和配置,以及需要注意的细节

gopher协议 目录 gopher协议 &#xff08;1&#xff09;安装一个cn &#xff08;2&#xff09;使用Gopher协议发送一个请求&#xff0c;环境为&#xff1a;nc起一个监听&#xff0c;curl发送gopher请求 &#xff08;3&#xff09;使用curl发送http请求&#xff0c;命令为 …

【MATLAB】PSO粒子群优化LSTM(PSO_LSTM)的时间序列预测

有意向获取代码&#xff0c;请转文末观看代码获取方式~也可转原文链接获取~ 1 基本定义 PSO粒子群优化LSTM&#xff08;PSO-LSTM&#xff09;是一种将粒子群优化算法&#xff08;PSO&#xff09;与长短期记忆神经网络&#xff08;LSTM&#xff09;相结合的混合模型。该算法通过…

Kubernetes技术与架构-集群管理

Kubernetes技术与架构提供支撑工具支持集群的规划、安装、创建以及管理。 数字证书 用户可以使用easyrsa、openssl、cfssl工具生成数字证书&#xff0c;在kubernetes集群的api server中部署数字证书用于访问鉴权 资源管理 如上所示&#xff0c;定义一个服务类service用于负…

计算机视觉技术-目标检测数据集

目标检测领域没有像MNIST和Fashion-MNIST那样的小数据集。 为了快速测试目标检测模型&#xff0c;我们收集并标记了一个小型数据集。 首先&#xff0c;我们拍摄了一组香蕉的照片&#xff0c;并生成了1000张不同角度和大小的香蕉图像。 然后&#xff0c;我们在一些背景图片的随机…