链 接:点击打开链接
题 意:Ignatius去到一个n*m密宫求公主,他要从(0,0)点走到(n-1,m-1)点,每走一个点代表一秒,求花费的最少时间
其中 . :代表可以走 X :代表陷阱不可以走 n:代表有n个妖怪,走此处要花费n秒杀怪
思 路:广度优先搜索 + 优先队列(每次从队列中选步数最少的) + 递归打印路径
代 码:
#include<iostream>
#include<string.h>
#include<string>
#include<queue>
#include<stdio.h>
using namespace std;
struct node
{
int x,y,step;
friend bool operator<(node n1,node n2)//优先选步数少的
{
return n2.step<n1.step;
}
}s;
char map[200][200];
int visited[200][200];
int N,M;
int dir[4][2]={-1,0,1,0,0,-1,0,1};
int flag=0;//标记是否能到
int path[200][200];//保存路径
int time;
int guai[200][200];//怪的个数
int bfs()
{
priority_queue<node>q;
node temp,m;
s.x=0;
s.y=0;
s.step=0;
visited[s.x][s.y]=-1;
q.push(s);
while(!q.empty())
{
temp=q.top();//优先队列出队为top
q.pop();
for(int i=0;i<4;i++)
{
m.x=temp.x+dir[i][0];
m.y=temp.y+dir[i][1];
if(m.x==(N-1)&&m.y==(M-1))
{
path[m.x][m.y]=i;//记录方向
return temp.step+1+visited[m.x][m.y];
}
else
{
if(m.x>=0&&m.x<N&&m.y>=0&&m.y<M&&visited[m.x][m.y]!=-1)//可走
{
if(visited[m.x][m.y]==0)//无怪
m.step=temp.step+1;
else //有怪
m.step=temp.step+1+visited[m.x][m.y];
visited[m.x][m.y]=-1;
path[m.x][m.y]=i;//记录方向
q.push(m);
}
}
}
}
return 0;
}
void PATH(int x,int y)//打印路径
{
int x1,y1;
if(path[x][y]==-1)
return;
x1=x-dir[path[x][y]][0];
y1=y-dir[path[x][y]][1];
PATH(x1,y1);
cout<<time<<"s:"<<"("<<x1<<","<<y1<<")"<<"->"<<"("<<x<<","<<y<<")"<<endl;
time++;
while(guai[x][y]--)
{
cout<<time<<"s:FIGHT AT ("<<x<<","<<y<<")"<<endl;
time++;
}
}
int main()
{
while(cin>>N>>M)
{
flag=0;
memset(guai,0,sizeof(guai));
memset(path,-1,sizeof(path));
for(int i=0;i<N;i++)
for(int j=0;j<M;j++)//可以走的标记为0,有怪的标记为怪的个数,不能走的 或走过的标记为-1
{
cin>>map[i][j];
if(map[i][j]=='.')
visited[i][j]=0;
else if(map[i][j]=='X')
visited[i][j]=-1;
else
visited[i][j]=guai[i][j]=map[i][j]-'0';
}
int sum=0;
sum=bfs();
if(sum)
{
cout<<"It takes "<<sum<<" seconds to reach the target position, let me show you the way."<<endl;
time=1;
PATH(N-1,M-1);
}
else
cout<<"God please help our poor hero."<<endl;
cout<<"FINISH"<<endl;
}
return 0;
}