DFS(混境之地)

#include <iostream>
using namespace std;
const int N=1e3+9;
const int tmax=1;
bool visit[N][N][tmax+1];//这样只可以代表0,1
int h[N][N];
bool flag=false;
int n,m,k;
int A,B,C,D;
int dx[]={0,0,-1,1};
int dy[]={1,-1,0,0};
bool inmp(int x,int y){
  if(x>=1&&x<=n&&y>=1&&y<=m) return true;
  else return false;
}
 void dfs(int x,int y ,int t){
   if(flag||(x==C&&y==D)){
     flag=true;
     return;
   }
   if(visit[x][y][t]) return;
   visit[x][y][t]=true;
   
   for(int i=0;i<4;++i){
     int nx=x+dx[i];
     int ny=y+dy[i];
     if(!inmp(nx,ny)) continue;

     //先不用燃料
     //当这样设置的时候会提前剪枝。例如(先往上面访问,并且可以进入if语句,那么visit[x][y][t]就置为true,然后发现上面行不通的时候开始往下面走,但是这个时候这个visit[x][y][t]已经设为true,这就导致其他三个方向的无法进入。)
     //最好的方法就是到大(x,y)点,设置为true,然后开始以这个为圆心,往外面扩展
     if(h[x][y]>h[nx][ny]){
      dfs(nx,ny,t);
     }
     if(h[x][y]+k>h[nx][ny]&&t<tmax){//并且还有燃料可以用
       dfs(nx,ny,t+1);
     }
   } 
 }
int main()
{
  cin>>n>>m>>k;
 cin>>A>>B>>C>>D;
 //布尔值默认为0
 for(int i=1;i<=n;++i){
   for(int j=1;j<=m;++j){
     cin>>h[i][j];
   }
 }
 dfs(A,B,0);
 cout<<(flag?"Yes":"No");
  // 请在此输入您的代码
  return 0;
}

问题描述 小蓝有一天误入了一个之地。 好消息是:他误打误撞拿到了一张地图,并从中获取到以下信息: 之地是一个 n⋅m 大小的矩阵,其中第 i 行第 j 列的的点 hij 表示第 i 行第 j 列的高度。 他现在所在位置的坐标为 (A,B) ,而这个之地出口的坐标为 (C,D) ,当站在出口时即表示可以逃离之地。 小蓝有一个喷气背包,使用时,可以原地升高 k 个单位高度。 坏消息是: 由于小蓝的体力透支,所以只可以往低于当前高度的方向走。 喷漆背包燃料不足,只可以最后使用一次。 小蓝可以往上下左右四个方向行走,不消耗能量。 小蓝想知道他能否逃离这个之地,如果可以逃离这里,输入 Yes ,反之输出 No 。 输入格式 第 1 行输入三个正整数 n,m 和 k , n,m 表示之地的大小, k 表示使用一次喷气背包可以升高的高度。 第 2 行输入四个正整数 A,B,C,D ,表示小蓝当前所在位置的坐标,以及之地出口的坐标。 第 3 行至第 n+2 行,每行 m 个整数,表示之地不同位置的高度。 输出格式 输出数据共一行一个字符串: 若小蓝可以逃离之地,则输出 Yes 。 若小蓝无法逃离之地,则输出 No 。 package practice; import java.util.*; public class a21 { static int n; static int m; static int k; static int a; static int b; static int c; static int d; static int[][] dp; static boolean[][] f; public static void main(String[] args) { System.out.println(); Scanner sc = new Scanner(System.in); n = sc.nextInt(); m = sc.nextInt(); dp = new int[n][m]; k = sc.nextInt(); a = sc.nextInt() - 1; b = sc.nextInt() - 1; c = sc.nextInt() - 1; d = sc.nextInt() - 1; f = new boolean[n][m]; for(int i = 0; i < n; i++) { for(int j = 0; j < m; j++) { dp[i][j] = sc.nextInt(); } } dfs(a, b, 0); if(f[c][d]) { System.out.println("Yes"); }else { System.out.println("No"); } } public static void dfs(int x, int y, int flag) { f[x][y] = true; int[] x1 = {-1, 1, 0, 0}; int[] y1 = {0, 0, -1, 1}; for(int i = 0; i < 4; i++) { int x2 = x + x1[i]; int y2 = y + y1[i]; if(x2 < 0 || x2 > dp.length - 1 || y2 < 0 || y >= dp[0].length - 1 || f[x2][y2] == true) { continue; } if(dp[x2][y2] < dp[x][y]) { dfs(x2, y2, flag); }else { if(dp[x2][y2] < dp[x][y] + k && flag == 0) { dfs(x2, y2, 1); } } } } }
03-10
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值