描述
佐助被大蛇丸诱骗走了,鸣人在多少时间内能追上他呢?
已知一张地图(以二维矩阵的形式表示)以及佐助和鸣人的位置。地图上的每个位置都可以走到,只不过有些位置上有大蛇丸的手下,需要先打败大蛇丸的手下才能到这些位置。鸣人有一定数量的查克拉,每一个单位的查克拉可以打败一个大蛇丸的手下。假设鸣人可以往上下左右四个方向移动,每移动一个距离需要花费1个单位时间,打败大蛇丸的手下不需要时间。如果鸣人查克拉消耗完了,则只可以走到没有大蛇丸手下的位置,不可以再移动到有大蛇丸手下的位置。佐助在此期间不移动,大蛇丸的手下也不移动。请问,鸣人要追上佐助最少需要花费多少时间?
输入
输入的第一行包含三个整数:M,N,T。代表M行N列的地图和鸣人初始的查克拉数量T。0 < M,N < 200,0 ≤ T < 10
后面是M行N列的地图,其中@代表鸣人,+代表佐助。*代表通路,#代表大蛇丸的手下。
输出
输出包含一个整数R,代表鸣人追上佐助最少需要花费的时间。如果鸣人无法追上佐助,则输出-1。
-
BFS板子
不知道为啥很玄学的W了又很玄学的A了:D
#include<cstdio>
#include<cstring>
using namespace std;
int n,m,x1,y1,
X[5]={ 0, 1, 0,-1},
Y[5]={ 1, 0,-1, 0};
//右 下 左 上
int a[403][403],
kl[403][403];
int main()
{
int x[100010],y[100010],//坐标
t[100010],//时间
k[100010],//查克拉
f[100010],//方向
h,l;
h=l=1;f[1]=4;//一开始没有方向
scanf("%d%d%d",&n,&m,&k[h]);
//我就n行m列你能咋滴:D
for(int i=1;i<=n;++i)
{
char c; scanf("%c",&c);//吃空格
for(int j=1;j<=m;++j)
{
scanf("%c",&c);
switch(c)
{
case '#':a[i][j]=1;break;//手下
case '@':x[1]=i;y[1]=j;break;//起点
case '+':x1=i;y1=j;break;//终点
}
}
}
memset(kl,-1,sizeof(kl));//防止下面查克拉没了后判断出错
kl[x[1]][y[1]]==k[h];
do
{
for(int i=0;i<4;++i)//循环方向
if(f[h]!=(i+2)%4)//不和之前的方向相反
{
int xx=x[h]+X[i],
yy=y[h]+Y[i];//移动后的坐标
if(xx>=1&&xx<=n&&yy>=1&&yy<=m)//在地图里
if(k[h]-a[xx][yy]>=0)//能打过手下
if(k[h]-a[xx][yy]>kl[xx][yy])//查克拉比以前要多
//加了这句就A了???
{
if(xx==x1&&yy==y1)//追到了
{printf("%d",t[h]+1);return 0;}
++l;//继续追
f[l]=i;//方向记录
x[l]=xx;y[l]=yy;//存坐标
t[l]=t[h]+1;//+1s
k[l]=k[h]-a[xx][yy];//查克拉
kl[xx][yy]=k[l];
}
}
++h;
}
while(h<=l);
printf("-1");
return 0;
}