题意: 输入n*m的迷宫,‘X’为墙,‘.'代表可走,n代表此处有n个怪兽(1<=n<=9),你必须花n秒才能从该处走过,每移动一格,花费一秒。最后要找到到达终点所用时间最短的一条路,并按要求输出该路。起点为(0,0)终点为(n-1,m-1)。
因为要比较是否为最小用时路径,则用深搜。
#include<iostream>
#include<string.h>
#include<queue>
#define INF 10000;
using namespace std;
typedef struct
{
int x,y;
}Point;
char map[110][110];
Point fa[110][110]; //逆向搜索,由终点向起点搜,fa[][]存的是当前位置的前一步所在位置。
int step[110][110]; //表示的是起点(这里实际指的是终点(n-1,m-1))到该点的时间。
queue<Point> q;
Point e;
int d[4][2]={-1,0,0,1,1,0,0,-1}; //四个方向上x、y轴上的变化。
int flag,n,m;
void bfs()
{
Point cur,next;
e.x=n-1; e.y=m-1;
if(map[n-1][m-1]=='.') step[n-1][m-1]=0; //终点也可能有怪兽,初始化“起点”所用时间。
else if(judge(n-1,m-1)) step[n-1][m-1]=map[n-1][m-1]-'0';
while(!q.empty()) q.pop();
q.push(e); //将"起点"入队列
while (!q.empty())
{
cur=q.front() ; q.pop();
if(cur.x==0&&cur.y==0) //如果,找到一条路标记,但因为该条路并不一定为最小用时路,所以,不能退出循环。
{
flag=1;
}
for (int i=0;i<4;i++)
{
next.x=cur.x+d[i][0]; next.y=cur.y+d[i][1]; //下面分情况,若为'.'则step[next.x][next.y]++.
if(map[next.x][next.y]!='X'&&next.x>=0&&next.x<n&&next.y>=0&&next.y<m)
{
int len; //若为n,则step[next.x][next.y]相应加n
if(map[next.x][next.y]!='.') {len=map[next.x][next.y]-'0';}
else len=0;
if (step[cur.x][cur.y]+1+len<step[next.x][next.y])
{
step[next.x][next.y]=step[cur.x][cur.y]+1+len;
fa[next.x][next.y].x=cur.x; fa[next.x][next.y].y=cur.y;
q.push(next);
}
}
}
}
return ;
}
int main()
{
while (scanf("%d%d",&n,&m)!=EOF)
{
for(int i=0;i<n;i++)
{
scanf("%s",map[i]);
for(int j=0;j<m;j++) step[i][j]=INF;
}
flag=0;
bfs();
if(flag==1)
{
printf("It takes %d seconds to reach the target position, let me show you the way.\n",step[0][0]);
int x=0,y=0;
for(int i=0;i<step[0][0];i++)
{
if(map[x][y]!='.'&&map[x][y]!='X')
{
for(int j=0;j<map[x][y]-'0';j++)
{
printf("%ds:FIGHT AT (%d,%d)\n",i+1,x,y);
i++;
}
}
if(x!=n-1||y!=m-1)
printf("%ds:(%d,%d)->(%d,%d)\n",i+1,x,y,fa[x][y].x,fa[x][y].y);
int temp=fa[x][y].x; y=fa[x][y].y;
x=temp;
}
}
else printf("God please help our poor hero.\n");
printf("FINISH\n");
}
return 0;
}