您的位置:首页 > 其它

杭电 HDU 1072 Nightmare

2013-07-19 17:31 429 查看
http://acm.hdu.edu.cn/showproblem.php?pid=1072

看到这个题发现它可以走重复路,所以一开始就不知道怎么写,然后百度了一下,看了一下别人的思路。主要就是判重条件的选择。

这个题由于可以走重复路,所以判重的标准不是看这个路是否已经走过,由于要看炸弹是否到时间,所以可以根据炸弹的剩余时间来进行判重,因为当你走到当前位置时剩余时间和前面走过的时间一样,那么再走完全没有意义。

所以我在我的代码里面用了一个二维数组st来存到达当前位置时剩余时间,当现在炸弹剩余的时间大于以前的时间时就可以走,否则直接忽略这条线路。

AC代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>

#define MAX 99999

using namespace std;

struct Node
{
int x,y;
int nub; //当前走的步数
int time;//距离爆炸的时间
};

int dir[4][2] = {{0,1},{0,-1},{1,0},{-1,0}};
int n,m,minnub;
int map[10][10];
int st[10][10];   //记录到每个位置时剩余时间

void Bfs(Node p)
{
Node now,next;
queue<Node> q;
int i;
p.nub = 0;
p.time = 6;
q.push(p);
map[p.x][p.y] = 0;   //把起点标记为墙,不可再走
while(!q.empty())
{
now = q.front();
q.pop();
if(now.time == 0)
{
continue;
}
if(map[now.x][now.y] == 4)
{
now.time = 6;
}
if(map[now.x][now.y] == 3)
{
if(now.nub < minnub)
{
minnub = now.nub;
}
continue;
}
//      printf("%d %d %d %d\n",now.x,now.y,now.nub,now.time);
for(i = 0; i < 4; i++)
{
next.x = now.x + dir[i][0];
next.y = now.y + dir[i][1];
next.nub = now.nub + 1;      //走的步数加一
next.time = now.time - 1;    //时间减一
//如果接下来的路能走,并且剩余的时间比以前要多,则可以继续走
if(map[next.x][next.y] != 0 && next.time > st[next.x][next.y])
{
st[next.x][next.y] = next.time;
q.push(next);
}
}
}
}

int main()
{
int t,i,j,nub;
Node b;
scanf("%d",&t);
while(t--)
{
memset(map,0,sizeof(map));   //初始化全为墙
memset(st,0,sizeof(st));     //重置在所有位置剩余时间为0
minnub = MAX;
scanf("%d%d",&n,&m);
for(i = 1; i <= n; i++)
{
for(j = 1; j <= m; j++)
{
scanf("%d",&map[i][j]);
if(map[i][j] == 2)
{
b.x = i;
b.y = j;
}
}
}
Bfs(b);
if(minnub == MAX)
{
printf("-1\n");
}
else
{
printf("%d\n",minnub);
}
}

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  搜索 杭电ACM BFS