鸣人和佐助——BFS+三维数组判重

本人水平有限,仅供学习,如有发现错误,感谢指出。

描述
已知一张地图(以二维矩阵的形式表示)以及佐助和鸣人的位置。地图上的每个位置都可以走到,只不过有些位置上有大蛇丸的手下,需要先打败大蛇丸的手下才能到这些位置。鸣人有一定数量的查克拉,每一个单位的查克拉可以打败一个大蛇丸的手下。假设鸣人可以往上下左右四个方向移动,每移动一个距离需要花费1个单位时间,打败大蛇丸的手下不需要时间。如果鸣人查克拉消耗完了,则只可以走到没有大蛇丸手下的位置,不可以再移动到有大蛇丸手下的位置。佐助在此期间不移动,大蛇丸的手下也不移动。请问,鸣人要追上佐助最少需要花费多少时间?
输入
输入的第一行包含三个整数:M,N,T。代表M行N列的地图和鸣人初始的查克拉数量T。0 < M,N < 200,0 ≤ T < 10
后面是M行N列的地图,其中@代表鸣人,+代表佐助。*代表通路,#代表大蛇丸的手下。
输出
输出包含一个整数R,代表鸣人追上佐助最少需要花费的时间。如果鸣人无法追上佐助,则输出-1。

题目链接 : 传送门(点我)


分析:

  • 朴素的广搜中,队列中存储了哪些信息? 1.节点坐标 2.节点step ,所以说,队列中节点存储的是状态。
  • 在该题中,节点的状态是什么?1.坐标 2.步数 3.查克拉能量

那么这里要用三维数组来判重,为什么?
因为存在通过相同点时,而查克拉此时不同,导致的结果是不同的,所以,我们判的其实是状态

AC代码:

#include<bits/stdc++.h>
using namespace std;
#define MAXN 210

char mp[MAXN][MAXN];
int vis[MAXN][MAXN][MAXN];
int xx[4]={
    
    0,0,-1,1},yy[4]={
    
    -1,1,0,0};
int m,n,c;
struct node{
    
    
    int x,y;
    int t;//left 查克拉
    int time;
};
node s,f;//start final

queue<node>q;

int main()
{
    
    
    cin>>m>>n>>c;
    for(int i=0;i<m;i++){
    
    //initialization
        for(int j=0;j<n;j++){
    
    
            cin>>mp[i][j];
            if(mp[i][j]=='@')s.x=i,s.y=j,s.time=0,s.t=c;//start
            if(mp[i][j]=='+')f.x=i,f.y=j,f.time=-1;//final
        }
    }
    q.push(s);vis[s.x][s.y][s.t]=1;
    while(q.size()!=0){
    
    
        node t = q.front();
        q.pop();
        if(t.x==f.x&&t.y==f.y){
    
    
            f.time=t.time;break;
        }

        for(int i=0;i<4;i++){
    
    
            node z;
            z.x=t.x+xx[i];z.y=t.y+yy[i];z.time=t.time+1;z.t=t.t;
            if(z.x<0||z.x>=m||z.y<0||z.y>=n||vis[z.x][z.y][z.t]==1)continue;//cross the border
            if(mp[z.x][z.y]=='#'){
    
    //go to 查克拉
                if(z.t>=1)z.t--;//查克拉reduce
                else continue; // 查克拉 not enough
            }
            vis[z.x][z.y][z.t]=1;
            q.push(z);
        }
    }
    return cout<<f.time<<endl,0;
}

猜你喜欢

转载自blog.csdn.net/weixin_43615816/article/details/114665199