哈理工OJ 1286迷宫宝藏(这个bfs有点意思)

飞机票带你看题: http://acm.hrbust.edu.cn/index.php?m=ProblemSet&a=showProblem&problem_id=1286

//这里的代码是我之前A的,大家参考一下思路即可,这个题目的关键在于不用标记是否到达过的点,可以重复去走
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <queue>
#include <limits.h>
using namespace std;
struct node
{
    int x,y,v;
}first,now,next;
int way[4][3]={{1,0},{0,1},{0,-1},{-1,0}};
int vis[105][105][105];   ///这个是关键
int n,m,value;
char map1[105][105];
int bfs(node first);
int main()
{
    int T;
    scanf("%d%*c",&T);
    //getchar();
    while(T--)
    {
        scanf("%d %d%*c",&n,&m);
        //getchar();
        n++;
        m++;

        int flag=0;
        for(int i=0;i<n;i++)
        {
            for(int j=0;j<m;j++)
           {
                scanf("%c",&map1[i][j]);

                if(map1[i][j] == '*')
                {
                    first.x =i;
                    first.y =j;
                    first.v =0;
                    map1[i][j] = '0';
                }

                if(map1[i][j] == '.')
                    map1[i][j] = '0';

            }
            scanf("%*c");///getchar()
        }

        scanf("%d",&value);
        //printf("The first value is %d\n",value);
        for(int i=0;i<n;i++)
            for(int j=0;j<m;j++)
                for(int k=0;k<105;k++)
                    vis[i][j][k] = 10000; ///下面会说明。


        if(value == 0)
               printf("0\n");
        else    printf("%d\n",bfs(first));
    }
    return 0;
}
bool judge(int x,int y)
{
    if(x<0||x>=n||y<0||y>=m||map1[x][y] == '#')
        return true;

    return false;
}
int bfs(node first)
{
    queue <node> q;
    vis[first.x][first.y][first.v] = 0;
    //printf("First is %d\n",vis[first.x][first.y][first.v]);
    //first.v = 0;
    q.push(first);
    while(!q.empty())
    {
        now = q.front();
        q.pop();
        for(int i=0;i<4;i++)
        {
            next.x = now.x + way[i][0];
            next.y = now.y + way[i][1];
            if(judge(next.x,next.y))
                continue;///以上为BFS的基础内容

            next.v = now.v + map1[next.x][next.y]-'0';  ///可以获得的宝物价值

            if(next.v == value)
                return vis[now.x][now.y][now.v]+1;///vis[x][y][v]数组表示的在(x,y)这点获得v价值所需要的步数
            if(next.v > value)
                continue;

            if(vis[next.x][next.y][next.v] > vis[now.x][now.y][now.v]+1)            ///这里我们已经初始化为1000了,如果你多次以v价值访问(x,y)这点就会判断是否值得,只有将这点于大于上一点+1的步数是才可以压入队列。
             {

                 vis[next.x][next.y][next.v] = vis[now.x][now.y][now.v]+1;
                 q.push(next);
             }
        }
    }
    return -1;
}

你可能感兴趣的:(搜索,迷宫,bfs,OJ,哈理工)