鸣人和佐助BFS

描述
佐助被大蛇丸诱骗走了,鸣人在多少时间内能追上他呢?
已知一张地图(以二维矩阵的形式表示)以及佐助和鸣人的位置。地图上的每个位置都可以走到,只不过有些位置上有大蛇丸的手下,需要先打败大蛇
丸的手下才能到这些位置。鸣人有一定数量的查克拉,每一个单位的查克拉可以打败一个大蛇丸的手下。假设鸣人可以往上下左右四个方向移动,每移
动一个距离需要花费1个单位时间,打败大蛇丸的手下不需要时间。如果鸣人查克拉消耗完了,则只可以走到没有大蛇丸手下的位置,不可以再移动到
有大蛇丸手下的位置。佐助在此期间不移动,大蛇丸的手下也不移动。请问,鸣人要追上佐助最少需要花费多少时间?

鸣人和佐助BFS_第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

分析:

  • 广度搜索,一层层推进,最短距离就是追上佐助的层数
  • 用s(r,c,depth,money)表示某个节点的状态(横坐标,纵坐标,层数,访问的剩余钱币数)
  • 由于有坐标,钱币的限制,我们要用三维数组visited[maxn][maxn][10]标记,在s点向子节点(四个方向)扩展时,如果子节点满足
    *位置,如果visited[r][c][s.money]==0,说明未访问过可以访问
    #位置,如果visited[r][c][s.money-1]==0,说明未访问过,可以访问

    AC代码
#include 
#include 
#include 
using namespace std;
const int maxn=210;
int visited[maxn][maxn][10]={0};
char G[maxn][maxn];
struct Point
{
    int r,c,depth,money;
    Point(int rr=0,int cc=0,int dd=0,int mm=0):r(rr),c(cc),depth(dd),money(mm){};
};
int X[4]={1,0,-1,0};
int Y[4]={0,1,0,-1};//方向数组
int main()
{
    int M,N,T,I,J;
    cin>>M>>N>>T;
    queue<Point>que;
    for(int i=0;i<M;i++)
    {
        for(int j=0;j<N;j++)
        {
            cin>>G[i][j];
            if(G[i][j]=='+')  I=i,J=j;
            else if(G[i][j]=='@')
            {
                que.push(Point(i,j,0,T));
                visited[i][j][0]=1;//已访问
            }
        }
    }//¹¹Í¼
    while(!que.empty())
    {
        Point s=que.front();
        if(s.r==I&&s.c==J)
        {
            cout<<s.depth<<endl;
            return 0;
        }
        else
        {
            int rr,cc;
            for(int i=0;i<4;i++)
            {
                rr=s.r+X[i],cc=s.c+Y[i];
                if(rr>=0&&rr<M&&cc>=0&&cc<N)//在范围
                {
                    if((s.money>0&&G[rr][cc]=='#')&&!visited[rr][cc][s.money-1])//未访问
                    {
                        que.push(Point(rr,cc,s.depth+1,s.money-1));
                        visited[rr][cc][s.money-1]=1;
                    }//可能出现到达守卫时不同路径的钱币数不同,但是少的先走了,显然钱币数多的走得更远
                    else if(G[rr][cc]!='#'&&!visited[rr][cc][s.money])//未访问
                    {
                        que.push(Point(rr,cc,s.depth+1,s.money));
                        visited[rr][cc][s.money]=1;
                    }
                }
            }
            que.pop();
        }
    }
    if(que.empty()) cout<<-1<<endl;
    return 0;
}

你可能感兴趣的:(广度搜索BFS)