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"; } }