题目描述
小明是个大胖子,或者说是个大大胖子,如果说正常人占用 1×11×1 的面积,小明要占用 5×55×5 的面积。
由于小明太胖了,所以他行动起来很不方便。当玩一些游戏时,小明相比小伙伴就吃亏很多。
小明的朋友们制定了一个计划,帮助小明减肥。计划的主要内容是带小明玩一些游戏,让小明在游戏中运动消耗脂肪。走迷宫是计划中的重要环节。
朋友们设计了一个迷宫,迷宫可以看成是一个由 n×n 个方阵组成的方阵,正常人每次占用方阵中 1×11×1 的区域,而小明要占用 5×55×5 的区域。小明的位置定义为小明最正中的一个方格。迷宫四周都有障碍物。
为了方便小明,朋友们把迷宫的起点设置在了第 33 行第 33 列,终点设置在 了第 n−2 行第 n−2 列。
小明在时刻 00 出发,每单位时间可以向当前位置的上、下、左、右移动单 位 1 的距离,也可以停留在原地不动。小明走迷宫走得很辛苦,如果他在迷宫里面待的时间很长,则由于消耗了很多脂肪,他会在时刻 k 变成一个胖子,只占用 3×33×3 的区域。如果待的时间更长,他会在时刻 2k 变成一个正常人,只占用 1×11×1 的区域。注意,当小明变瘦时迷宫的起点和终点不变。
请问,小明最少多长时间能走到迷宫的终点。注意,小明走到终点时可能瘦了也可能没有变瘦。
输入描述
输入的第一行包含两个整数 ,n,k (1≤n≤300,1≤k≤1000)。
接下来 n 行,每行一个由 n 个字符组成的字符串,字符为 + 表示为空地, 字符为 \* 表示为阻碍物。
输出描述
输出一个整数,表示答案。
输入输出样例
示例
输入
9 5
+++++++++
+++++++++
+++++++++
+++++++++
+++++++++
***+*****
+++++++++
+++++++++
+++++++++
输出
16
运行限制
语言 | 最大运行时间 | 最大运行内存 |
C++ | 1s | 256M |
C | 1s | 256M |
Java | 2s | 256M |
Python3 | 3s | 256M |
代码:
import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;
public class 大胖子走迷宫 {
static char[][] map;
static boolean[][] vis;
static int[] dx = {1, -1, 0, 0};
static int[] dy = {0, 0, -1, 1};
static int n;
static int k;
static int time = 0;// 时间
static int tmp = 2;// 肥胖程度
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
n = scanner.nextInt();
k = scanner.nextInt();
map = new char[n][n];
vis = new boolean[n][n];
//初始化地图
for (int i = 0; i < n; i++) {
map[i] = scanner.next().toCharArray();
}
bfs();
}
private static void bfs() {
Queue<int[]> queue = new LinkedList<>();
queue.offer(new int[] { 2, 2 });
vis[2][2] = true;
while (!queue.isEmpty()) {
int len = queue.size();
while (len-- > 0) {
int[] nums = queue.poll();
int x = nums[0];
int y = nums[1];
// 出口
if (x == n - 3 && y == n - 3) {
System.out.println(time);
return;
}
//模拟四个方向
for (int i = 0; i < 4; i++) {
int a = x + dx[i];
int b = y + dy[i];
if (a - tmp >= 0 && a + tmp < n && b - tmp >= 0
&& b + tmp < n && !vis[a][b] && check(a, b)) {
vis[a][b] = true;
queue.offer(new int[] { a, b });
}
}
//原地不动
queue.offer(new int[] { x, y });
}
time++;
//根据时间改变肥胖程度
if (time == k) {
tmp = 1;
}
if (time == 2 * k) {
tmp = 0;
}
}
}
/**
* 判断身体是否在障碍物里
* @param x
* @param y
* @return
*/
private static boolean check(int x, int y) {
for (int i = x - tmp; i <= x + tmp; i++) {
for (int j = y - tmp; j <= y + tmp; j++) {
if (map[i][j] == '*') {
return false;
}
}
}
return true;
}
}