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 其它信息