DFS进阶——混境之地5

混境之地5

dfs+回溯+简单剪枝

题目分析

小蓝的起始位置为(A,B),终点位置为(C,D),询问能否从起点走到终点。我们注意这是一个矩阵图,每次走的时候可以上下左右四个方向走,一般而言我们只需要从起点去走就可以了,那么我们从起点进入dfs。如下代码,

java 复制代码
dfs(A,B);

进入dfs之后,我们先标记 v i s i t [ A ] [ B ] = 1 visit[A][B]=1 visit[A][B]=1,表示这个点我们已经遍历过了,在遍历图的过程每个节点只能被遍历一遍。然后我们尝试向上下左右四个方向走,对于x,y,向上走就是x+(-1),y+0,向下走就是x+1,y+0,向左走就是y+(-1),x+0,向右走就是y+1,x+0。那么我们可以把这里的+(-1)或者+0放在数组里,即

java 复制代码
static int []dx = {1,-1,0,0};//x的变化
static int []dy = {0,0,1,-1};//y的变化

然后遍历数组里的值,就可以得到向四个方向走后的坐标。得到坐标之后,我们要判断坐标是否越界,并且还要判断下一个坐标是否之前已经被遍历过,同样我们要判断我们可不可以走向下一个坐标,如果没有越界那么我们就可以走入下一个坐标,对下一个坐标进行递归,即

java 复制代码
public static void dfs(int x,int y,int u){
   visit[x][y] = 1;
   for(int i = 0; i < 4; i ++){
       int x1 = x + dx[i];
       int y1 = y + dy[i];
       if(x1<1||x1>n||y1<1||y1>m||visit[x1][y1]==1){
           continue;
       }
       if(c[x1][y1]<=c[x][y]){
           dfs(x1,y1);
       }
   }
}

上述做法是没有考虑可以使用喷气背包的情况,接下来考虑可以使用喷气背包。如果可以使用喷气背包,那么对于下一个我们要遍历的点,如果可以到达它,那么就不使用喷气背包,如果不可以到达,我们就考虑要不要在这个点使用喷气背包,因为我只能使用一次,在哪个点使用可以帮助我们走到终点我们是不确定的。所以每个点我都要尝试一下,那么这就涉及到了回溯,因为对于一个我不能到达的点,我有使用背包和不使用背包两种选择。

因为我们要回溯,所以visit数组要在dfs的附近进行改变,这样dfs结束后方便把visit数组复原。回溯会增加dfs的执行次数,那么如果可以剪枝我们尽量剪枝,这里flag表示我们是否走到了终点,如果走到了直接退出,并且在dfs结束后我们也判断一下,如果之前已经走到过终点了,那么直接退出就行。

java 复制代码
public static void dfs(int x,int y,int u){
   if(x==C&&y==D) {
	   flag=1;
	   return;
   }
   for(int i = 0; i < 4; i ++){
       int x1 = x + dx[i];
       int y1 = y + dy[i];
       if(x1<1||x1>n||y1<1||y1>m||visit[x1][y1]==1){
           continue;
       }
       if(c[x1][y1]<=c[x][y]){
    	   visit[x1][y1] = 1;
           dfs(x1,y1,u);
           if(flag==1) return;
           visit[x1][y1] = 0;
       }
       else{
           if(u==1&&c[x1][y1]-c[x][y]<=k){
        	   visit[x1][y1] = 1;
               dfs(x1,y1,0);
               if(flag==1) return;
               visit[x1][y1] = 0;
           }
       }
   }
}
题目代码
java 复制代码
import java.util.Scanner;
public class Main{
static int n;
static int m;
static int A;
static int B;
static int C;
static int D;
static int k;
static int [][]visit;
static int [][]c;
static int []dx = {1,-1,0,0};
static int []dy = {0,0,1,-1};
static int flag = 0;
public static void main(String[] args){
   Scanner s = new Scanner(System.in);
   n = s.nextInt();
   m = s.nextInt();
   k = s.nextInt();
   A = s.nextInt();
   B = s.nextInt();
   C = s.nextInt();
   D = s.nextInt();
   c = new int [n+3][m+3];
   visit = new int [n+3][m+3];
   for(int i = 1; i <= n;i ++){
       for(int j = 1; j <= m; j ++){
           c[i][j] = s.nextInt();
           visit[i][j] = -1;
       }
   }
   visit[A][B] = 1;
   dfs(A,B,1);
   if(flag == 1)
       System.out.println("Yes");
   else
       System.out.println("No");
}
public static void dfs(int x,int y,int u){
   if(x==C&&y==D) {
	   flag=1;
	   return;
   }
   for(int i = 0; i < 4; i ++){
       int x1 = x + dx[i];
       int y1 = y + dy[i];
       if(x1<1||x1>n||y1<1||y1>m||visit[x1][y1]==1){
           continue;
       }
       if(c[x1][y1]<=c[x][y]){
    	   visit[x1][y1] = 1;
           dfs(x1,y1,u);
           if(flag==1) return;
           visit[x1][y1] = 0;
       }
       else{
           if(u==1&&c[x1][y1]-c[x][y]<=k){
        	   visit[x1][y1] = 1;
               dfs(x1,y1,0);
               if(flag==1) return;
               visit[x1][y1] = 0;
           }
       }
   }
}
}
相关推荐
python算法(魔法师版)2 分钟前
基于机器学习鉴别中药材的方法
深度学习·线性代数·算法·机器学习·支持向量机·数据挖掘·动态规划
JNU freshman1 小时前
力扣第435场周赛讲解
算法·leetcode·蓝桥杯
眼镜哥(with glasses)1 小时前
蓝桥杯python基础算法(2-2)——基础算法(B)——模拟(上)
算法
赵鑫亿2 小时前
7.DP算法
算法·dp
iqay2 小时前
【C语言】填空题/程序填空题1
c语言·开发语言·数据结构·c++·算法·c#
还有糕手3 小时前
算法【有依赖的背包】
算法·动态规划
pursuit_csdn4 小时前
力扣 347. 前 K 个高频元素
算法·leetcode
wen__xvn4 小时前
每日一题洛谷B3865 [GESP202309 二级] 小杨的 X 字矩阵c++
c++·算法·矩阵
makabaka_T_T4 小时前
25寒假算法刷题 | Day1 | LeetCode 240. 搜索二维矩阵 II,148. 排序链表
数据结构·c++·算法·leetcode·链表·矩阵
辞半夏丶北笙5 小时前
最近最少使用算法(LRU最近最少使用)缓存替换算法
java·算法·缓存