总时间限制:
1000ms
内存限制:
65536kB
描述
佐助被大蛇丸诱骗走了,鸣人在多少时间内能追上他呢?
已知一张地图(以二维矩阵的形式表示)以及佐助和鸣人的位置。地图上的每个位置都可以走到,只不过有些位置上有大蛇丸的手下,需要先打败大蛇丸的手下才能到这些位置。鸣人有一定数量的查克拉,每一个单位的查克拉可以打败一个大蛇丸的手下。假设鸣人可以往上下左右四个方向移动,每移动一个距离需要花费1个单位时间,打败大蛇丸的手下不需要时间。如果鸣人查克拉消耗完了,则只可以走到没有大蛇丸手下的位置,不可以再移动到有大蛇丸手下的位置。佐助在此期间不移动,大蛇丸的手下也不移动。请问,鸣人要追上佐助最少需要花费多少时间?
输入
输入的第一行包含三个整数:M,N,T。代表M行N列的地图和鸣人初始的查克拉数量T。0 < M,N < 200,0 ≤ T < 10
后面是M行N列的地图,其中@代表鸣人,+代表佐助。*代表通路,#代表大蛇丸的手下。
输出
输出包含一个整数R,代表鸣人追上佐助最少需要花费的时间。如果鸣人无法追上佐助,则输出-1。
样例输入
样例输入1
4 4 1
#@##
**##
###+
****
样例输入2
4 4 2
#@##
**##
###+
****
样例输出
样例输出1
6
样例输出2
4
查克拉的不同,使同一个点在走过后,也有不同。
#include<bits/stdc++.h>//Writed by Wangzhimin Date 2022.05,02
using namespace std;
int r,c,ckl;//行列查克拉
char team[205][205];//存字符的数组
char visited[205][205][15];//走过的点,查克拉的不同,使相同的点有不同的值
int p[4][2]={0,1,0,-1,1,0,-1,0};//方向
struct step{//结构体中有位置查克拉和步数
int x;
int y;
int k;
int steps;
step(int xx,int yy,int kk,int ss):x(xx),y(yy),k(kk),steps(ss){
};
};
int main(){
scanf("%d%d%d",&r,&c,&ckl);//第一行
memset(visited,0,sizeof(visited));
queue<step>q;
int i,j,flag=0;
for(i=0;i<r;i++)//输入字符
scanf("%s",team[i]);
int r1,c1,r2,c2;//查找起点和终点
for(i=0;i<r;i++)
for(j=0;j<c;j++)
{
if(team[i][j]=='@')
{
r1=i;c1=j;
}
if(team[i][j]=='+')
{
r2=i;c2=j;
}
}
q.push(step(r1,c1,ckl,0));
visited[r1][c1][ckl]=1;//开始置1
int x,y,ckl,steps;//为下面用的变量
while(!q.empty())
{
step s=q.front();
if(s.x==r2&&s.y==c2){//找到了
cout<<s.steps<<endl;
return 0;}
for(i=0;i<4;i++){//向上下左右移动
x=s.x+p[i][0];
y=s.y+p[i][1];
ckl=s.k;
steps=s.steps+1;
if(x<0||y<0||x>=r||y>=c||visited[x][y][ckl]==1)
continue;//不符合条件就返回做
if(team[x][y]=='#'){//有查克拉吗
if(ckl>0)
ckl--;
else
continue;//不符合
}
q.push(step(x,y,ckl,steps));//入队
visited[x][y][ckl]=1;
}
q.pop();
}
cout<<"-1"<<endl;
return 0;
}