营救天使(java)

题目描述

天使被恶魔抓住,关在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;
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值