Hero

題目描述

  500年前,NowCoder是我國最卓越的劍客。他英俊瀟灑,並且機智過人^_^。 忽然有一天,NowCoder心愛的公主被魔王困在了一個巨大的迷宮中。NowCoder據說這個消息已是兩天之後了,他知道公主在迷宮中還能堅持T天,他急忙趕到迷宮,開始處處尋找公主的下落。 時間一點一點的過去,NowCoder仍是沒法找到公主。最後當他找到公主的時候,美麗的公主已經死了。今後NowCoder鬱鬱寡歡,茶飯不思,一年後追隨公主而去了。T_T 500年後的今天,NowCoder託夢給你,但願你幫他判斷一下當年他是否有機會在給定的時間內找到公主。 他會爲你提供迷宮的地圖以及所剩的時間T。請你判斷他是否能救出心愛的公主。java

1.1 輸入描述:

  題目包括多組測試數據。
  每組測試數據以三個整數N,M,T(00)開頭,分別表明迷宮的長和高,以及公主能堅持的天數。
  緊接着有M行,N列字符,由」.」,」*」,」P」,」S」組成。其中
  「.」 表明可以行走的空地。
  「*」 表明牆壁,NowCoder不能今後經過。
  「P」 是公主所在的位置。
  「S」 是NowCoder的起始位置。
  每一個時間段裏NowCoder只能選擇「上、下、左、右」任意一方向走一步。
  輸入以0 0 0結束。算法

1.2 輸出描述:

  若是能在規定時間內救出公主輸出「YES」,不然輸出「NO」。測試

1.3 輸入例子:

4 4 10
....
....
....
S**P
0 0 0

1.4 輸出例子:

YES

 

2 解題思路

 

  可使用廣度優先遍歷。從起始點一圈一圈遍歷,最早遍歷的位置就是最少用的時間,每一圈消耗一個單位的時間。
這裏寫圖片描述
  圖2-1 廣度優先遍歷spa

3 算法實現

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

 

4 測試結果

這裏寫圖片描述

5 其它信息

相關文章
相關標籤/搜索