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

来源:互联网 发布:php nginx 403 编辑:程序博客网 时间:2024/05/29 16:01

飞机票带你看题: 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;}
0 0
原创粉丝点击