【算法练习】迷宫与陷阱(多维度BFS)

在这里插入图片描述
在这里插入图片描述

import java.io.*;
import java.util.*;

class node {
	int x, y, k;
	node(int x, int y, int k) {
		this.x = x;
		this.y = y;
		this.k = k;
	}
}
public class Main {
    static BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
    public static void main(String[] args) throws IOException {
    	String[] input = reader.readLine().trim().split(" ");
    	int n = Integer.parseInt(input[0]);
    	int k = Integer.parseInt(input[1]);
    	char[][] map = new char[n + 1][n + 1];
    	for (int i = 0; i < n; i++) map[i] = reader.readLine().trim().toCharArray();
    	// 三个状态:走到的格子、以及到达该格子的无敌步数
    	boolean[][][] vis = new boolean[n + 1][n + 1][k + 1];
    	int[] x = new int[] {-1,1,0,0};
    	int[] y = new int[] {0,0,-1,1};
    	vis[0][0][0] = true;
    	Queue<node> queue = new LinkedList<>();
    	queue.offer(new node(0, 0, 0));  // 起点没有无敌
    	int cnt = 0;
    	boolean flag = false;
    	while (!queue.isEmpty()) {
    		int size = queue.size();
    		for (int i = 0; i < size; i++) {
    			node cur = queue.poll();
    			// 找到终点
    			if (cur.x == n - 1 && cur.y == n - 1) {
    				System.out.println(cnt);
    				return;
    			}
    			for (int j = 0; j < 4; j++) {	
    				int tx = cur.x + x[j];
    				int ty = cur.y + y[j];
    				// 目前有的无敌步数,注意除了墙壁不能走,陷阱和普通路都会消耗无敌步数
    				int kk = cur.k;
    				if (tx < 0 || ty < 0 || tx >= n || ty >= n) continue;
    				// 如果当前状态已经走过,或者是墙壁,都不能走(无论是否无敌)
    				if (map[tx][ty] == '#') continue;
    				if (map[tx][ty] == 'X') {
    					// 陷阱,无敌状态可以走
    					if (kk > 0) {
    						if (vis[tx][ty][kk - 1]) continue;
    						queue.offer(new node(tx, ty, kk - 1));
    						vis[tx][ty][kk - 1] = true;
    					}
    				} else if (map[tx][ty] == '%') {
    					if (vis[tx][ty][kk > 0 ? kk - 1 : 0]) continue;
    					// 变无敌,获得k步
    					queue.offer(new node(tx, ty, k));
    					vis[tx][ty][kk > 0 ? kk - 1 : 0] = true;
    					// 拿了之后就不能再拿
    					map[tx][ty] = '.';
    				} else {
    					if (vis[tx][ty][kk > 0 ? kk - 1 : 0]) continue;
    					queue.offer(new node(tx, ty, kk > 0 ? kk - 1 : 0));
    					vis[tx][ty][kk > 0 ? kk - 1 : 0] = true;
    				}
    			}
    		}
    		// 整个完成一轮,步数++
    		cnt++;
    	}
    	System.out.println(-1);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

@u@

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值