hdu1026深搜+广搜(优先队列)

来源:互联网 发布:阳西县官方网络问政 编辑:程序博客网 时间:2024/06/07 00:36

题意:从(0,0)点走到(n-1,m-1)点的最短时间,地图上的数字代表杀怪所需要的时间。

思路:

1.求最短时间所以选择广搜,

2.途中有杀怪耽误的时间,所以还要用优先队列,

3.打印路径广搜办不到,只能用深搜,所以采用广搜找路的同时记录改点是从哪个点走过来的,

4.使用递归从(n-1,m-1)点找到到(0,0)确定路径,并用回溯打印从(0,0)到(n-1,m-1)的路径。




代码+具体讲解

#include<stdio.h>
#include<string.h>
#include<queue>
using namespace std;
struct node
{
int x,y,time;
friend bool operator<(node a,node b)        //使用优先队列
{
return b.time<a.time;
}
};
int arr,times,temp;
int n,m;
int flag[105][105];
int map[105][105];
int blood[105][105];
int dir[4][2]={0,1,1,0,-1,0,0,-1};
bool yes(int xx,int yy)
{
if(xx<0||xx>=n||yy<0||yy>=m) return 1;
if(map[xx][yy]==-1)          return 1;
return 0;
}
int bfs()
{
int i;
priority_queue<node>q;
node first,tail;
first.x=0;first.y=0;
first.time=0;
q.push(first);
while(!q.empty())
{
first=q.top();
q.pop();
if(first.x==n-1&&first.y==m-1) return first.time;
for(i=0;i<4;i++)
{
tail.x=first.x+dir[i][0];
tail.y=first.y+dir[i][1];
if(yes(tail.x,tail.y)) continue;
tail.time=first.time+map[tail.x][tail.y]+1;
map[tail.x][tail.y]=-1;
flag[tail.x][tail.y]=i;          //记录改点是从哪个方向来的
q.push(tail);
}
}
return 0;
}
void p(int x,int y)
{
int next_x,next_y;
if(x==0&&y==0) return;
next_x=x-dir[flag[x][y]][0];
next_y=y-dir[flag[x][y]][1];
p(next_x,next_y);
printf("%ds:(%d,%d)->(%d,%d)\n",temp++,next_x,next_y,x,y);
while(blood[x][y]--)
printf("%ds:FIGHT AT (%d,%d)\n",temp++,x,y);
}


int main()
{
char str[111];int i,j;
while(scanf("%d%d",&n,&m)!=EOF)
{
memset(blood,0,sizeof(blood));
memset(flag,0,sizeof(flag));
memset(map,0,sizeof(map));
for(i=0;i<n;i++)
{
scanf("%s",str);
for(j=0;str[j];j++)
{
if(str[j]=='.')map[i][j]=0;
else if(str[j]=='X')map[i][j]=-1;
else map[i][j]=blood[i][j]=str[j]-48;       
}
}
map[0][0]=-1;
times=bfs();
if(times)
{
temp=1;
printf("It takes %d seconds to reach the target position, let me show you the way.\n",times);
p(n-1,m-1);
}
else
{
printf("God please help our poor hero.\n");
}
printf("FINISH\n");
}
return 0;
}

0 0