您的位置:首页 > 其它

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

2016-03-08 17:07 337 查看
飞机票带你看题: 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 搜索 迷宫