题目
-
Problem Description
You play a new RPG. The world map in it is represented by a grid of n × m cells. Any playing character staying in some cell can move from this cell in four directions — to the cells to the left, right, forward and back, but not leaving the world map.Monsters live in some cells. If at some moment of time you are in the cell which is reachable by some monster in d steps or less, he immediately runs to you and kills you.
You have to get alive from one cell of game field to another. Determine whether it is possible and if yes, find the minimal number of steps required to do it.
-
Input
The first line contains three non-negative integers n, m and d (2 ≤ n·m ≤ 200000, 0 ≤ d ≤ 200000) — the size of the map and the maximal distance at which monsters are dangerous.Each of the next n lines contains m characters. These characters can be equal to «.», «M», «S» and «F», which denote empty cell, cell with monster, start cell and finish cell, correspondingly. Start and finish cells are empty and are presented in the input exactly once.
-
Output
If it is possible to get alive from start cell to finish cell, output minimal number of steps required to do it. Otherwise, output «-1». -
input
5 7 1
S.M...M
.......
.......
M...M..
......F
- output
12
题意
有一个n*m的地图,上面有怪物,起点,终点,每个怪物有行动距离d,在怪物d格范围之内都是危险的,无法通过
问起点到终点的最短路,如果不能到达则输出-1
思路
首先处理怪物,将危险范围全部标记在地图上,约等于围墙,然后就是走迷宫,找最短路,用bfs
因为地图太大无法用二维数组储存,只能用一维数组,需要处理坐标,存(x,y)转一维比较容易,我是存一维转(x,y)…
bfs
每次都从队列中拿出一个点p,查找p附近的点,如果有符合条件 且 未被访问过的点,则加入队列,值为p值+1,直到队列为空 或者 目标点 被访问,此时每个点上的值都是从起点去到该点的最短路
代码
#include <bits/stdc++.h>
using namespace std;
int m[200010];
int N,M,D;
int ans;
int fr,fc;
queue<int>q,moves;
int nr[4]= {-1,0,1,0};
int nc[4]= {0,-1,0,1};//上左下右
int transform(int r,int c)
{
return c+(r-1)*M;
}
void bfs(int r,int c)
{
moves.push(transform(r,c));
m[transform(r,c)]=0;
while(!moves.empty()) {
r=moves.front()%M?moves.front()/M+1:moves.front()/M;
c=moves.front()%M?moves.front()%M:M;
moves.pop();
for(int i=0; i<4; i++) {
int dr=r+nr[i],dc=c+nc[i];
if(dr>0&&dr<=N&&dc>0&&dc<=M) {
if(m[transform(dr,dc)]==-1) {
m[transform(dr,dc)]=m[transform(r,c)]+1;
moves.push(transform(dr,dc));
}
}
}
}
}
void monster()
{
int r,c;
while(!q.empty()) {
r=q.front()%M?q.front()/M+1:q.front()/M;
c=q.front()%M?q.front()%M:M;
q.pop();
for(int i=0; i<4; i++) {
int dr=r+nr[i],dc=c+nc[i];
if(dr>0&&dr<=N&&dc>0&&dc<=M) {
if( m[transform(dr,dc)] < m[transform(r,c)]-1 ) {
m[transform(dr,dc)]=m[transform(r,c)]-1;
q.push(transform(dr,dc));
}
}
}
}
}
int main()
{
int sr,sc;
while( scanf("%d %d %d",&N,&M,&D)!=EOF ) {
getchar();
for(int r=1; r<=N; ++r) {
for(int c=1; c<=M; ++c) {
scanf("%c",&m[transform(r,c)]);
if(m[transform(r,c)]=='M') q.push(transform(r,c)),m[transform(r,c)]=D;
else if(m[transform(r,c)]=='.') m[transform(r,c)]=-1;
else if(m[transform(r,c)]=='S') m[transform(r,c)]=-1,sr=r,sc=c;
else if(m[transform(r,c)]=='F') m[transform(r,c)]=-1,fr=r,fc=c;
}
getchar();
}
monster();
if(m[transform(sr,sc)] != -1 || m[transform(fr,fc)] != -1 ) {
printf("-1\n");
continue;
}
while(!moves.empty())
moves.pop();
bfs(sr,sc);
if(m[transform(fr,fc)]==-1)
printf("-1\n");
else
printf("%d\n",m[transform(fr,fc)]);
}
return 0;
}