Description
龙龙最近迷上了一款名叫 PUBG(PLAYERUNKNOWN’S BATTLEGROUNDS)的手游,那是一款关乎生存挑战的 RPG 逃亡游戏。
考虑到游戏的环节过于复杂,龙龙决定简化一下场景:整个地图可以看做一个长为
n
n
n 宽为
m
m
m 的二维格点平面。龙龙需要从
(
x
1
,
y
1
)
(x_1,y_1)
(x1,y1) 逃亡到
(
x
2
,
y
2
)
(x_2,y_2)
(x2,y2) 以逃离毒圈,但有些格点上存在障碍#
不能行走,有些格点是沙地.
。龙龙只能移动在允许行走的沙地上,同时每一时刻,龙龙只能朝着当前位置周围的上、下、左、右四个方向移动。同时因为龙龙使用了能量饮料,每分钟最多可以朝着一个方向行走
k
k
k 步。
毒圈快要来啦,请你帮龙龙尽快安排一下可行的路线,使得它能够以最短的时间顺利进圈。
Input
第一行输入三个正整数
n
,
m
n, m
n,m 和
k
k
k
(
1
≤
n
,
m
,
k
≤
1000
)
(1 \leq n, m, k \leq 1000)
(1≤n,m,k≤1000) 表示地图的大小还有龙龙每分钟最多可以移动的步数;
接下来
n
n
n 行,每行包含
m
m
m 个字符,其中第
i
i
i行第
j
j
j 个字符表示坐标
(
i
,
j
)
(i,j)
(i,j) 的路况,它可能是#
,这表示这个格点是障碍区,不能行走,也可能是.
表示沙地;
最后一行输入四个正整数
x
1
,
y
1
,
x
2
,
y
2
x_1, y_1, x_2, y_2
x1,y1,x2,y2 由空格间隔开,表示龙龙的初始位置和目标位置。
Output
请输出一个正整数 t t t,表示龙龙从 ( x 1 , y 1 ) (x_1, y_1) (x1,y1) 到 ( x 2 , y 2 ) (x_2,y_2) (x2,y2)进圈最少需要的时间(分钟),如果龙龙最终不能进圈,则请输出 − 1 -1 −1。
Hint
对于样例,龙龙第一分钟走 4 4 4 步,从 ( 1 , 3 ) (1, 3) (1,3) 到 ( 1 , 1 ) (1, 1) (1,1) ,第二分钟从 ( 1 , 1 ) (1, 1) (1,1) 到 ( 3 , 1 ) (3, 1) (3,1),第三分钟从 ( 3 , 1 ) (3, 1) (3,1) 走到 ( 3 , 3 ) (3, 3) (3,3) 顺利进圈。
测试输入 | 期待的输出 |
---|---|
3 4 4 . . . . . # # # . . . . 1 3 3 3 \begin{matrix}3&4&4&\\ . & . & . & .\\ . & \# & \# & \#\\ . & . & . & .\\ 1 & 3 & 3 & 3\\\end{matrix} 3...14.#.34.#.3.#.3 | 3↵ |
思路
本题和 22.地下城与勇士 还是有很大的相似度,甚至因为去除了时间还要稍微简单一点。对于某一点(i,j),需要分别从上下左右四个方向,移动
1
~
k
1 \verb|~| k
1~k步。如果越界或碰墙,break
;如果访问过,continue
;否则就入队列,visited++
。注意题目坐标是从
1
1
1开始,变一下。其他就和22题完全一样了。
代码
#include <stdio.h>
#include <string.h>
#define N 1010
char map[N][N];
int visited[N][N], n, m, k, x, y;
struct Queue
{
int zb[N*N][2];
int time[N*N];
int front;
int rear;
} queue;
void init()
{
memset(visited, 0, sizeof(visited));
memset(queue.zb, -1, sizeof(queue.zb));
memset(queue.time, -1, sizeof(queue.time));
queue.front = 0;
queue.rear = 0;
}
void push(int i, int j, int t)
{
queue.zb[queue.rear][0] = i;
queue.zb[queue.rear][1] = j;
queue.time[queue.rear] = t;
queue.rear++;
}
void pop()
{
queue.front++;
}
int isOK(int i, int j)
{
if (i < 0 || i >= n || j < 0 || j >= m)
return 0;
else if (map[i][j] == '#')
return 0;
else if (map[i][j] == '.' && visited[i][j] == 0)
return 1;
else
return -1;
}
int main()
{
int k, i, j, step, p, q;
scanf("%d %d %d", &n, &m, &k);
for (i = 0; i < n; i++)
{
scanf("%s", map[i]);
}
scanf("%d %d %d %d", &p, &q, &x, &y);
x--;
y--;
init();
push(p-1, q-1, 0);
while (1)
{
pop();
int t = queue.time[queue.front - 1] + 1;
i = queue.zb[queue.front - 1][0];
j = queue.zb[queue.front - 1][1];
if(t==0){
printf("-1\n");
return 0;
}
// up
for (step = 1; step <= k; step++)
{
if (i == x && j + step == y)
{
printf("%d\n", t);
return 0;
}
int flag = isOK(i, j + step);
if (flag == -1)
continue;
else if (flag == 1)
{
push(i, j + step, t);
visited[i][j + step] = 1;
}
else
break;
}
// down
for (step = 1; step <= k; step++)
{
if (i == x && j - step == y)
{
printf("%d\n", t);
return 0;
}
int flag = isOK(i, j - step);
if (flag == -1)
continue;
else if (flag == 1)
{
push(i, j - step, t);
visited[i][j - step] = 1;
}
else
break;
}
// left
for (step = 1; step <= k; step++)
{
if (i - step == x && j == y)
{
printf("%d\n", t);
return 0;
}
int flag = isOK(i - step, j);
if (flag == -1)
continue;
else if (flag == 1)
{
push(i - step, j, t);
visited[i - step][j] = 1;
}
else
break;
}
// right
for (step = 1; step <= k; step++)
{
if (i + step == x && j == y)
{
printf("%d\n", t);
return 0;
}
int flag = isOK(i + step, j);
if (flag == -1)
continue;
else if (flag == 1)
{
push(i + step, j, t);
visited[i + step][j] = 1;
}
else
break;
}
}
}