这是一道广搜好题,好题就那么多做一道少一道。
题意很简单:从(0,0)点开始到(n-1,m-1)点最短花费时间。’.’:可以走,’X’:不允许走,‘2’:数字表示需要花费多少时间把这个怪兽杀掉,勇士每走一步需要花费1s,每次走只能走上下左右四个方向
思路:用优先队列处理广搜,然后用一个数组path[][]记录路径,最后从终点找到起点用回溯的方法输出。
直接上代码:
欢迎大家指点。
#include<stdio.h>
#include<string>
#include<string.h>
#include<algorithm>
#include<iostream>
#include<queue>
using namespace std;
const int N=200+10;
struct node
{
int x,y;
int step;
friend bool operator <(node a,node b)
{
return a.step>b.step;//step小的优先级高
}
}e;
bool mark;
int n,m;
int path[N*2][N*2];//记录路径方向
int fx[4][2]={1,0,-1,0,0,1,0,-1};//上下左右四个方向
char s[N][N];
bool vis[N*2][N*2];//记录是否已经访问过
int bfs()
{
priority_queue<node>q;//优先队列
e.x=0,e.y=0,e.step=0;
vis[0][0]=true;
while(!q.empty())
q.pop();
q.push(e);
node now,last;
while(!q.empty())
{
now=q.top();
q.pop();
for(int i=0;i<4;i++)
{
last.x=now.x+fx[i][0];
last.y=now.y+fx[i][1];
if(last.x>=n||last.x<0||last.y>=m||last.y<0)
{
continue;
}
if(s[last.x][last.y]=='X'||vis[last.x][last.y])
continue;
if(s[last.x][last.y]=='.')
{
last.step=now.step+1;
q.push(last);
vis[last.x][last.y]=true;
}
else if(s[last.x][last.y]>='0'&&s[last.x][last.y]<='9')
{
last.step=now.step+1+s[last.x][last.y]-'0';
q.push(last);
vis[last.x][last.y]=true;
}
path[last.x][last.y]=i;
if(last.x==n-1&&last.y==m-1)//找到终点跳出
{
mark=true;
}
if(mark)
break;
}
if(mark)
break;
}
return last.step;
}
int cnt;
void pls(int n1,int m1)//回溯输出路径
{
if(path[n1][m1]==-1)return ;
int x=n1-fx[path[n1][m1]][0];
int y=m1-fx[path[n1][m1]][1];
pls(x,y);
if(s[x][y]>='0'&&s[x][y]<='9')
{
for(int i=0;i<s[x][y]-'0';i++)
{
printf("%ds:FIGHT AT (%d,%d)\n",cnt++,x,y);
}
}
printf("%ds:(%d,%d)->(%d,%d)\n",cnt++,x,y,n1,m1);
}
int main()
{
while(~scanf("%d%d",&n,&m))
{
mark=false;
memset(s,0,sizeof(s));
memset(path,-1,sizeof(path));
memset(vis,false,sizeof(vis));
for(int i=0;i<n;i++)
{
scanf("%s",s[i]);
}
int sum=bfs();
if(!mark)//没有找到终点
{
printf("God please help our poor hero.\n");
printf("FINISH\n");
}
else
{
printf("It takes %d seconds to reach the target position, let me show you the way.\n",sum);
cnt=1;
pls(n-1,m-1);
if(s[n-1][m-1]>='0'&&s[n-1][m-1]<='9')
for(int i=0;i<s[n-1][m-1]-'0';i++)
{
printf("%ds:FIGHT AT (%d,%d)\n",cnt++,n-1,m-1);
}
printf("FINISH\n");
}
}
return 0;
}