备注:带路径的bfs
这道题与普通的bfs相比有3个要点:
1.hero将会在有数字的格子上停留,直接用个数组fright[105][105]来保存。
2.要输出他每走一步的路径。每走一步他的方向(后继)都是不确定的,但是
他的前驱是确定的。所以,保存前驱就好。
3.输出的是最短时间,bfs出来的是最短的路径却不是最短的时间,所以要用优先队列根据时间来排序。
总结一下就是bfs+优先队列+路径保存。
//带路径的广搜 后继记录前驱
#include<iostream>
#include<cstring>
#include<queue>
using namespace std;
int fright[105][105];
int visit1[105][105];
char a[105][105];
struct Point{
int x;
int y;
};
struct Node{
int col;
int row;
int t;
};
struct cmp
{
bool operator ()(Node x, Node y)
{
return x.t > y.t;//小的优先级高
}
};
Point pre[105][105];
Node first,en;
int nexted[4][2]={0,1,0,-1,1,0,-1,0};
int n,m;
int bfs()
{
Node front,v;
priority_queue<Node,vector<Node>,cmp> q;
q.push(en);
while(!q.empty())
{
//cout<<"进入"<<endl;
front=q.top();//优先队列没有front方法。
q.pop();
if(front.col==0&&front.row==0)
{
printf("It takes %d seconds to reach the target position, let me show you the way.\n",front.t);
int x=front.col;
int y=front.row;
int key=1;
pre[n-1][m-1].x=-1;
while (pre[x][y].x != -1) //不断寻找前驱直到到达终点
{
int tx = pre[x][y].x;
int ty = pre[x][y].y;
printf ("%ds:(%d,%d)->(%d,%d)\n", key++, x, y, tx, ty);
if (a[tx][ty] != '.')
for (int i = 0; i < a[tx][ty] - '0'; i++)
printf ("%ds:FIGHT AT (%d,%d)\n", key++, tx, ty);
x = tx;
y = ty;
}
return 1;
}
for(int i=0;i<4;i++)
{
v.col=front.col+nexted[i][0];
v.row=front.row+nexted[i][1];
v.t=front.t+fright[v.col][v.row]+1;
if(visit1[v.col][v.row]==1) continue;
if(a[v.col][v.row]=='X') continue;
if(v.col<0||v.row<0||v.col>=n||v.row>=m) continue;//刚开始忘了加等号,这样的小细节,可把我给害苦了。
q.push(v);
//记录前驱。。
pre[v.col][v.row].x=front.col;
pre[v.col][v.row].y=front.row;
//`````````````
visit1[v.col][v.row]=1;
}
}
return 0;
}
int main()
{
int flag;//标记能不能走到
while(scanf("%d%d",&n,&m)==2)
{
memset(fright,0,sizeof(fright));
memset(visit1,1,sizeof(visit1));
memset(a,0,sizeof(a));
memset(pre,0,sizeof(pre));
for(int i=0;i<n;i++)
for(int j=0;j<m;j++)
{
cin>>a[i][j];
visit1[i][j]=0;
//if(a[i][j]=='X') {
// for(int k=1;k<=9;k++)
//visited[i][j][k]=1;
//}
if(a[i][j]>='1'&&a[i][j]<='9')
{
int t=a[i][j]-'0';
fright[i][j]=t;
}
}
// first.col=0;
//first.row=0;
//first.t=0;
en.col=n-1;
en.row=m-1;
en.t=fright[n-1][m-1];
pre[n-1][m-1].x=-1;
flag=bfs();
if(!flag) cout<<"God please help our poor hero.\n";
cout<<"FINISH"<<endl;
}
return 0;
}