这篇文章让我收获相当大。。。做了4个小时,最后还是跑去看了别人的题解
1:思路:bfs+优先队列
用flag[x][y]记录走到(x,y)处,上一步走的方向(用0,1,2,3表示),flag[][]数组初始化都是-1。因为标记了flag数组,加上个判断,王子就不会走已经走过的路径了。bfs最先到达的一定是最快的,将每一个结点传入优先队列,一直取top。
2:自己收获:
1:bfs:
最开始自己是用dfs做,虽然代码很简单,但是复杂度实在是太高了,显示超时。bfs是和队列紧密联系的,因为是一层一层的取的嘛,将每一层都放进队列。
2:重载运算符:
我真是菜,c++重载运算符总是懵逼。。。
1:友元重载小于号,大于号
struct node{
int a;
friend bool<(node x,node y){
return x.a<y.a;
}
};
struct node{
int a;
friend bool>(node x,node y){
return x.a>y.a;
}
};
2:{}前面的const是必须加上的
struct node{
int a;
friend bool<(const node x)const{
return this->a < x.a.;
}
};
struct node{
int a;
friend bool>(const node x)const{
return this->a > x.a.;
}
};
优先队列的排列是根据小于号,所以只需要重载小于号就行了,将小于号变成实际的大于号
3:我感觉最骚的就是flag的使用,因为每个flag[x][y]记录的都是上一个位置到这里的方向,所以就用到了递归的思想来输出。
4:以为血量只有1,2,错了半天,傻叉
然后贴上代码
#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;
#define maxn 111
struct node{
int x;
int y;
int step;
bool operator< (const node x)const{
return this->step>x.step;
}
};
char map[maxn][maxn];
int flag[maxn][maxn];//记录方向
int n,m;
int dir[4][2]={{1,0},{0,1},{-1,0},{0,-1}};
int cnt;
int BFS()
{
priority_queue<node> q;
node Cur,Next;
Cur.x=0,Cur.y=0,Cur.step=0;
q.push(Cur);
while(!q.empty())
{
Cur=q.top();
q.pop();
if(n-1==Cur.x && m-1==Cur.y){
return Cur.step;
}
int i;
for(i=0;i<4;i++){
int xi=Cur.x+dir[i][0],yi=Cur.y+dir[i][1];
if(xi<0||n<=xi || yi<0||m<=yi ||'X'==map[xi][yi] || -1!=flag[xi][yi])//判断是否不能走
continue;
else{
flag[xi][yi]=i;//记录上一步走到这个地方的方向
if('1'<=map[xi][yi] && map[xi][yi]<='9'){
Next.x=xi,Next.y=yi,Next.step=Cur.step+1+map[xi][yi]-'0';
}else{
Next.x=xi,Next.y=yi,Next.step=Cur.step+1;
}
q.push(Next);
}
}
}
return -1;
}
void show(int x,int y)
{
if(0==x&&0==y){
return ;
}
int pre_x=x-dir[flag[x][y]][0],pre_y=y-dir[flag[x][y]][1];
show(pre_x,pre_y);
printf("%ds:(%d,%d)->(%d,%d)\n",cnt++,pre_x,pre_y,x,y);
if('1'<=map[x][y] && map[x][y]<='9'){
int temp=map[x][y]-'0';
for(temp;temp>0;temp--){
printf("%ds:FIGHT AT (%d,%d)\n",cnt++,x,y);
}
}
}
int main()
{
while(EOF!=scanf("%d %d",&n,&m))
{
getchar();
memset(flag,-1,sizeof(flag));
cnt=1;
int i,j;
char temp;
for(i=0;i<n;i++){
for(j=0;j<m;j++){
scanf("%c",&map[i][j]);
}
getchar();
}
int ans=BFS();
if(-1==ans){
printf("God please help our poor hero.\n");
}else{
printf("It takes %d seconds to reach the target position, let me show you the way.\n",ans);
show(n-1,m-1);
}
cout << "FINISH" << endl;
}
return 0;
}