S - 鸣人和佐助

S - 鸣人和佐助

题目:
佐助被大蛇丸诱骗走了,鸣人在多少时间内能追上他呢?

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


样例输入2
4 4 2
#@##
**##
###+


Sample Output
样例输出1
6

样例输出2
4

代码如下:

#include
#include
#include
#include
using namespace std;
#define MAX 250

int M,N,T;
int x,y,x2,y2;
int vis[MAX][MAX][15];
int direction[4][2] = {{1,0},{0,1},{-1,0},{0,-1}};
char a[MAX][MAX];
struct Node
{
    int xx,yy;
    int step;
    int tt;
};

int bfs()
{
	memset(vis,0,sizeof(vis));
    queue q;
    Node node1,node2;
    node1.xx = x;
    node1.yy = y;
    node1.step = 0;
    node1.tt = T;
    q.push(node1);
    vis[x][y][T] = 1;
    while(!q.empty())
    {
        node1 = q.front();
        q.pop();
        if(node1.xx == x2 && node1.yy == y2) return node1.step;
        for(int i = 0;i < 4;i++)
        {
            int dx = node1.xx + direction[i][0];
            int dy = node1.yy + direction[i][1];
            if(!vis[dx][dy][node1.tt] && dx >= 0 && dx < M && dy >= 0 && dy < N )
            {
                if(node1.tt <= 0 && a[dx][dy] == '#') continue;
                vis[dx][dy][node1.tt] = 1;
                node2.xx = dx;
                node2.yy = dy;
                node2.step = node1.step + 1;
                node2.tt = node1.tt;
                if(a[dx][dy] == '#' && node1.tt > 0) node2.tt = node1.tt - 1;
                q.push(node2);
            }
        }
    }
    return -1;
}

int main()
{
	int res;
    while(~scanf("%d%d%d",&M,&N,&T))
    {
        for(int i = 0;i < M;i++)
        {
            for(int j = 0;j < N;j++)
            {
                cin >> a[i][j];
                if(a[i][j] == '@') x = i,y = j;
                else if(a[i][j] == '+') x2 = i,y2 = j;
            }
        }
        res = bfs();
        cout << res << endl;
    }
    return 0;
}

这道题使用BFS可以完成,这里每次往队列中放入的结点包括横纵坐标以及当时已走步数以及查克拉量,当查克拉不为0的时候,无论什么点都可走,走过‘#’记得让查克拉减1,当查克拉为0是那么就只能走’*’,这时候只需步数加1就可以了.
输出‘-1’的条件,就是当队列为空的时候,也就是鸣人走不到佐助那里就输出-1.

这里需要注意的是:使用vis判重的时候不仅要考虑每个点的坐标位置,还需要考虑处在每个点的时候查克拉的量,因为处在相同的点查克拉的量不同会影响后续的进程。之前wa了好几次就是因为没考虑这点。

你可能感兴趣的:(DFS/BFS)