题目描述
天使被恶魔抓住,关在N行M列的矩阵的方格中,我们现在要从起始方格出发,去营救天使。我们每次只能在矩阵中往上或往下或往左或往右移动一格,且需耗时1秒。有些方格中有障碍物,不能进入;有些方格中有小鬼守卫,把它杀死还需另外耗时1秒。我们需要计算,到达天使所在方格的最少秒数。
输入
第1行是2个整数N、M,分别表示矩阵的行数和列数。
接下去是N行,每行M个字符,其中.表示可以进入的普通方格,x表示有小鬼守卫的方格,#表示有障碍物的方格,r表示起始方格,a表示天使所在方格。输出
如果能够营救,输出最少秒数,如果不能,输出-1。
样例输入
7 8 #.#####. #.a#..r. #..#x... ..#..#.# #...##.. .#...... ........
样例输出
13
思路
从起点开始沿着可行的四个方向进行广搜,当走到有怪物的地方需要时间再+1,遇到已经访问过的地方需要判断一下时间是否可以更少,将每个地方的时间都登记为可行的最小值即可
代码
import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;
public class Main {
static int n,m;
static char[][] map;
static boolean[][] visit;
static int[][] move = {{1,0},{-1,0},{0,1},{0,-1}};
static int[][] time;
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
n = in.nextInt();
m = in.nextInt();
map = new char[n][m];
visit = new boolean[n][m];
time = new int[n][m];
String s = in.nextLine();
for(int i=0;i<n;i++) {
s=in.nextLine();
for(int j=0;j<m;j++) {
map[i][j]=s.charAt(j);
}
}
for(int i=0;i<n;i++)
for(int j=0;j<m;j++)
if(map[i][j]=='r')
BFS(i,j);
}
public static void BFS(int x,int y) {
Queue<Node> queue = new LinkedList<Node>();
Node start = new Node(x,y,0,0);
queue.offer(start);
visit[x][y]=true;
int t=0;
while(!queue.isEmpty()) {
Node next = queue.poll();
for(int i=0;i<4;i++) {
x=next.x+move[i][0];
y=next.y+move[i][1];
t=time[next.x][next.y];
if(x>=0 && x<n && y>=0 && y<m && map[x][y]!='#') {
t++;
if(map[x][y]=='x')
t++;
if(visit[x][y]) {
if(t<time[x][y]) {
time[x][y]=t;
}
continue;
}
if(map[x][y]=='a') {
System.out.println(t);
return;
}
queue.offer(new Node(x,y,next.x,next.y));
visit[x][y]=true;
time[x][y]=t;
}
}
}
System.out.println(-1);
}
}
class Node{
int x;
int y;
int prex;
int prey;
Node(int x,int y,int prex,int prey){
this.x=x;
this.y=y;
this.prex=prex;
this.prey=prey;
}
}