500年前,NowCoder是我国最卓越的剑客。他英俊潇洒,并且机智过人^_^。 忽然有一天,NowCoder心爱的公主被魔王困在了一个巨大的迷宫中。NowCoder据说这个消息已是两天之后了,他知道公主在迷宫中还能坚持T天,他急忙赶到迷宫,开始处处寻找公主的下落。 时间一点一点的过去,NowCoder仍是没法找到公主。最后当他找到公主的时候,美丽的公主已经死了。今后NowCoder郁郁寡欢,茶饭不思,一年后追随公主而去了。T_T 500年后的今天,NowCoder托梦给你,但愿你帮他判断一下当年他是否有机会在给定的时间内找到公主。 他会为你提供迷宫的地图以及所剩的时间T。请你判断他是否能救出心爱的公主。java
题目包括多组测试数据。
每组测试数据以三个整数N,M,T(00)开头,分别表明迷宫的长和高,以及公主能坚持的天数。
紧接着有M行,N列字符,由”.”,”*”,”P”,”S”组成。其中
“.” 表明可以行走的空地。
“*” 表明墙壁,NowCoder不能今后经过。
“P” 是公主所在的位置。
“S” 是NowCoder的起始位置。
每一个时间段里NowCoder只能选择“上、下、左、右”任意一方向走一步。
输入以0 0 0结束。算法
若是能在规定时间内救出公主输出“YES”,不然输出“NO”。测试
4 4 10 .... .... .... S**P 0 0 0
YES
可使用广度优先遍历。从起始点一圈一圈遍历,最早遍历的位置就是最少用的时间,每一圈消耗一个单位的时间。
图2-1 广度优先遍历spa
import java.util.LinkedList; import java.util.List; import java.util.Scanner; /** * 解法一 * Declaration: All Rights Reserved !!! */ public class Main { public static void main(String[] args) { // Scanner scanner = new Scanner(System.in); Scanner scanner = new Scanner(Main.class.getClassLoader().getResourceAsStream("data.txt")); while (scanner.hasNext()) { // 迷宫大小 int col = scanner.nextInt(); int row = scanner.nextInt(); // 剩余时间 int time = scanner.nextInt(); if (row == 0 && col == 0 && time == 0) { break; } // NowCoder的开始位置 int px = 0; int py = 0; // 公主的位置 int sx = 0; int sy = 0; char[][] maze = new char[row][col]; for (int i = 0; i < row; i++) { String line = scanner.next(); maze[i] = new char[col]; for (int j = 0; j < col; j++) { maze[i][j] = line.charAt(j); if (maze[i][j] == 'P') { px = i; py = j; } else if (maze[i][j] == 'S') { sx = i; sy = j; } } } System.out.println(findPath(maze, px, py, sx, sy, time)); } scanner.close(); } /** * 迷宫找最短的路径,使用广度优先遍历 * * @param maze 迷宫 * @param px NowCoder的开始位置。横坐标 * @param py NowCoder的开始位置。纵坐标 * @param sx 公主的位置。横坐标 * @param sy 公主的位置。纵坐标 * @param time 剩余时间 * @return YES:在time时间内能够找到公主,NO:在time时间内找不到公主 */ private static String findPath(char[][] maze, int px, int py, int sx, int sy, int time) { // 迷宫大小 int row = maze.length; int col = maze[0].length; // 记录广度优先处理的,当前要处理的坐标 List<Integer> curr = new LinkedList<>(); // 记录广度优先处理的,下一圈的坐标 List<Integer> next = new LinkedList<>(); curr.add(px); curr.add(py); // 标记已经访问的位置 maze[px][py] = '*'; while (!curr.isEmpty()) { px = curr.remove(0); py = curr.remove(0); if (px == sx && py == sy) { return "YES"; } // System.out.println("(" + px + ", " + py + ")"); // 往上走 if (px - 1 >= 0 && maze[px - 1][py] != '*') { next.add(px - 1); next.add(py); maze[px - 1][py] = '*'; } // 往右走 if (py + 1 < col && maze[px][py + 1] != '*') { next.add(px); next.add(py + 1); maze[px][py + 1] = '*'; } // 往下走 if (px + 1 < row && maze[px + 1][py] != '*') { next.add(px + 1); next.add(py); maze[px + 1][py] = '*'; } // 往左走 if (py - 1 >= 0 && maze[px][py - 1] != '*') { next.add(px); next.add(py - 1); maze[px][py - 1] = '*'; } // 当前层处理完 if (curr.isEmpty()) { // 剩下的时间减小 time--; // 时间用完了尚未找到 if (time < 0) { return "NO"; } // 处理下一层 else { List<Integer> queue = curr; curr = next; next = queue; } } } return "NO"; } }