思路:bfs`
我们可以用三元组来存储鸣人所在的位置和查克拉数量x,y,t;
通过队列来进行BFS,
可以利用结构体,也可以利用容器来存储鸣人的位置
鸣人操作是分两种情况讨论:
1、 下一步是守卫即 ‘#’ ,查看查克拉的剩余的多少,若t<0
则直接continue,若t>0,则可以走下一步,查克拉减少1,f[x][y][t-1]为该位置的步数。
2、下一步是 道路 即 ‘ * ’ ,查克拉t不变,f[x][y][t];
#include<bits/stdc++.h>
using namespace std;
const int N=210;
char g[N][N];
int n,m,t;
typedef pair<int,pair<int,int>> plll;
plll q[N*N];
int f[N][N][11];
bool st[N][N][11];
int dx[4]={0,1,0,-1};
int dy[4]={1,0,-1,0};
int mx,my,zx,zy;
#define x first
#define y second
int ans=1e9;
void bfs()
{
memset(st,0,sizeof st);
int hh=0,tt=0;
q[tt]={t,{mx,my}};
st[mx][my][t]=true;
f[mx][my][t]=0;//t表示剩余查克拉
while(hh<=tt)
{
plll tx=q[hh++];
//cout<<tx.y.x<<" "<<tx.y.y<<" "<<tx.x<<endl;
for(int i=0;i<4;i++)
{
int a=tx.y.x+dx[i],b=tx.y.y+dy[i],c=tx.x;
if(a<0||b<0||a>=n||b>=m) continue;
if(g[a][b]=='+') //若找到佐助,则+1退出
{ans=min(ans,f[tx.y.x][tx.y.y][tx.x]+1);return ;}
if(g[a][b]=='#'&&c>0&&!st[a][b][c-1]) //如果这里是守卫,查克拉还有剩余,并且这里没到达过
{
f[a][b][tx.x-1]=f[tx.y.x][tx.y.y][tx.x]+1;
q[++tt]={tx.x-1,{a,b}};
st[a][b][c-1]=true;
}
else if(g[a][b]=='*'&&!st[a][b][c])
{
f[a][b][tx.x]=f[tx.y.x][tx.y.y][tx.x]+1;
q[++tt]={tx.x,{a,b}};
st[a][b][c]=true;
}
}
}
}
int main()
{
cin>>n>>m>>t;
for(int i=0;i<n;i++)
cin>>g[i];
for(int i=0;i<n;i++)
for(int j=0;j<m;j++)
{
if(g[i][j]=='@')
{
mx=i,my=j;
}
if(g[i][j]=='+')
{
zx=i,zy=j;
}
}
memset(f,0,sizeof f);
bfs();
if(ans!=1e9)
cout<<ans<<endl;
else puts("-1");
return 0;
}