题意:从S走到F,M是怪兽,输入的d是怪兽的攻击范围。怪兽走d步能到达的地方不能走。
用bfs预处理M点。当遇到其他M点并且是第一次遇见时,让其他M点也进行更新。预处理完了之后就可以再一个bfs求最短路径了。一开始用的dfs预处理M点结果被卡在了48组。开数组保存的这个图,
例如3 4就是
1 2 3 4
5 6 7 8
9 10 11 12
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <map>
#include <iostream>
#include <algorithm>
#include <set>
#include <vector>
#include <queue>
#include <ctime>
#include <stack>
using namespace std;
typedef long long ll;
int n,m,q,S,F,mp[200050],dd[200050],len[200050];
int cnt;
void bfs()
{
memset(len,-1,sizeof(len));
int l,r;
l=r=0;
if(mp[S]==0)
{
len[S]=0;
dd[r]=S;
r++;
}
while(l<r)
{
int xx=dd[l];
l++;
if(xx-m>0&&len[xx-m]==-1&&mp[xx-m]==0)///上
{
len[xx-m]=len[xx]+1,dd[r]=xx-m;
if(xx-m==F)
break;
r++;
}
if(xx%m!=0&&len[xx+1]==-1&&mp[xx+1]==0)///右
{
len[xx+1]=len[xx]+1,dd[r]=xx+1,r++;
if(xx+1==F)
break;
}
if(xx+m<cnt&&len[xx+m]==-1&&mp[xx+m]==0)///下
{
len[xx+m]=len[xx]+1,dd[r]=xx+m,r++;
if(xx+m==F)
break;
}
if(xx%m!=1&&len[xx-1]==-1&&mp[xx-1]==0)///左
{
len[xx-1]=len[xx]+1,dd[r]=xx-1,r++;
if(xx-1==F)
break;
}
}
}
void bbfs(int x)
{
int l,r;
l=r=0;
if(len[x]==-1)
{
dd[r++]=x;
len[x]=0;
}
while(l<r)
{
int xx=dd[l];
if(mp[xx]!=q)
len[xx]=-1;
l++;
if(xx-m>0)///上
{
if(mp[xx-m]==q&&len[xx-m]==-1)
{
len[xx-m]=0;
dd[r++]=xx-m;
}
else if(mp[xx]-1>mp[xx-m])
{
mp[xx-m]=mp[xx]-1;
if(len[xx-m]==-1)
dd[r++]=xx-m,len[xx-m]=0;
}
}
if(xx%m!=0)///右
{
if(mp[xx+1]==q&&len[xx+1]==-1)
{
len[xx+1]=0;
dd[r++]=xx+1;
}
else if(mp[xx]-1>mp[xx+1])
{
mp[xx+1]=mp[xx]-1;
if(len[xx+1]==-1)
dd[r++]=xx+1,len[xx+1]=0;
}
}
if(xx+m<cnt)///下
{
if(mp[xx+m]==q&&len[xx+m]==-1)
{
len[xx+m]=0;
dd[r++]=xx+m;
}
else if(mp[xx]-1>mp[xx+m])
{
mp[xx+m]=mp[xx]-1;
if(len[xx+m]==-1)
dd[r++]=xx+m,len[xx+m]=0;
}
}
if(xx%m!=1)///左
{
if(mp[xx-1]==q&&len[xx-1]==-1)
{
len[xx-1]=0;
dd[r++]=xx-1;
}
else if(mp[xx]-1>mp[xx-1])
{
mp[xx-1]=mp[xx]-1;
if(len[xx-1]==-1)
dd[r++]=xx-1,len[xx-1]=0;
}
}
}
}
void init()///预处理
{
memset(len,-1,sizeof(len));
for(int i=1; i<cnt; i++)
{
if(mp[i]==q+1)
{
bbfs(i);
}
}
}
void display()
{
for(int i=0; i<n; i++)
{
for(int j=1; j<=m; j++)
{
printf("%4d ",mp[i*m+j]);
}
printf("\n");
}
}
int main()
{
char str[200050];
scanf("%d%d%d",&n,&m,&q);
cnt=1;
for(int i=0; i<n; i++)
{
scanf("%s",str+1);
for(int j=1; j<=m; j++)
{
if(str[j]=='.')
{
mp[cnt++]=0;
}
else if(str[j]=='M')
{
mp[cnt++]=q+1;
}
else if(str[j]=='S')
{
S=cnt;
mp[cnt++]=0;
}
else if(str[j]=='F')
{
F=cnt;
mp[cnt++]=0;
}
}
}
init();
/// display();
///display();
bfs();
printf("%d\n",len[F]);
return 0;
}