dfs与bsf问题合集

在这里插入图片描述

> 网格类问题的 DFS 遍历方法

//网格 DFS 遍历的框架代码
void dfs(vector<vector<int>> grid, int r, int c) {
    // 判断 base case
    if (!inArea(grid, r, c)) {
        return;
    }
    // 如果这个格子不是岛屿,直接返回
    if (grid[r][c] != 1) {
        return;
    }
    grid[r][c] = 2; // 将格子标记为「已遍历过」
    
    // 访问上、下、左、右四个相邻结点
    dfs(grid, r - 1, c);
    dfs(grid, r + 1, c);
    dfs(grid, r, c - 1);
    dfs(grid, r, c + 1);
}

// 判断坐标 (r, c) 是否在网格中
bool inArea(vector<vector<int>> grid, int r, int c) {
    return 0 <= r && r < grid.size() 
        	&& 0 <= c && c < grid[0].size();
}


class Solution {
public:
    bool isValid(vector<vector<char>>& grid, int x, int y){
        return x >= 0 && y >= 0 && x < grid.size() && y < grid[0].size();
    }
    void dfs(vector<vector<char>>& grid, int x, int y){
        if(!isValid(grid, x, y))
            return;
        if(grid[x][y] != '1')
            return;
        
        grid[x][y] = '2';

        dfs(grid, x, y-1);
        dfs(grid, x+1, y);
        dfs(grid, x, y+1);
        dfs(grid, x-1, y);
    }

    int numIslands(vector<vector<char>>& grid) {
        int r = grid.size();
        int c = grid[0].size();

        int cnt = 0;
        for(int i = 0; i < r; i++){
            for(int j = 0; j < c; j++){
                if(grid[i][j] == '1'){
                    cnt++;
                    dfs(grid, i, j);
                    
                }
                    
            }
        }

        return cnt;
    }
};

在这里插入图片描述

#include <iostream>
#define MAXSIZE 15
using namespace std;


int n;
int cnt=1;
int arr[MAXSIZE][MAXSIZE];
int dp[MAXSIZE][MAXSIZE];


int dfs(int x,int y)//从右上角开始搜索 
{
	if(x>=n&&y<=1)return 0;//找到左下角或出界,退出 
	if(dp[x+1][y]>dp[x][y-1])dfs(x+1,y);//如果下边的值大于左边的值 
	if(dp[x][y-1]>dp[x+1][y])dfs(x,y-1);//如果左边的值大于下边的值 
	if(dp[x][y-1]==dp[x+1][y])//如果两点的路径之和相等 
	{
		cnt++;//路径数加1 
		dfs(x,y-1);
		dfs(x+1,y);
	} 
	return cnt;
}

int main()
{
	cin>>n;
	for(int i = 1; i <=n ; i++)
	{
		for(int j = 1; j <= n; j++)
		{
			cin>>arr[i][j];
		}
	}
	
	for(int i=n;i >= 1;i--)
	{
		for(int j = 1;j <= n;j++)
		{
			if(i==n&&j==1)dp[i][j]=arr[i][j];//从左下角开始,起点等于它本身 
			else if(i==n)//如果在第n行,则任一右边的数等于其左边数加上其本身 
				dp[i][j]=dp[i][j-1]+arr[i][j];
			else if(j==1)//如果在第1列,则任一上边的数等于其下边数加上其本身 
				dp[i][j]=dp[i+1][j]+arr[i][j];
			else//其他情况,在两种情况中选择大值加上它本身 
				dp[i][j]=max(dp[i][j-1],dp[i+1][j])+arr[i][j];
		}
	} 
	
	cout<<dfs(1,n)<<" "<<dp[1][n]<<endl;
	
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值