#include <iostream>
#include<cstdio>
#include<memory.h>
#include<queue>
using namespace std;
const int maxn=105;
char g[maxn][maxn];
int s[maxn][maxn];//记录步数
int dir[maxn][maxn];//记录方向
int m,n;
int dx[]={-1,1,0,0};
int dy[]={0,0,-1,1};
struct node{
public:
node():x(0),y(0),step(0){}
node(int _x,int _y,int _s):x(_x),y(_y),step(_s){}
public:
int x,y,step;
};
bool check(int x,int y){
if(x<0||y<0||x>m-1||y>n-1)return false;
if(g[x][y]=='X')return false;
return true;
}
void init(){
memset(dir,-1,sizeof(dir));
memset(s,-1,sizeof(s));
s[0][0]=0;
}
void bfs()
{
queue<node>q;
q.push(node(0,0,0));
while(!q.empty()){
node n=q.front();
q.pop();
for(int i=0;i<4;++i){
int newx=n.x+dx[i];
int newy=n.y+dy[i];
int newstep;
if(check(newx,newy)){
if(g[newx][newy]=='.')newstep=n.step+1;
else newstep=n.step+g[newx][newy]-'0'+1;
if(s[newx][newy]>newstep||s[newx][newy]==-1){//没有走过或时间更短
s[newx][newy]=newstep;
dir[newx][newy]=i;
q.push(node(newx,newy,newstep));
}
}
}
}
}
void print(int x,int y)
{
//cout<<x<<","<<y<<endl;
if(dir[x][y]==-1)return;
int nx=x-dx[dir[x][y]];
int ny=y-dy[dir[x][y]];
print(nx,ny);
printf("%ds:",s[nx][ny]+1);
printf("(%d,%d)->(%d,%d)\n",nx,ny,x,y);
if(g[x][y]!='.'){
int t=g[x][y]-'0';
for(int i=1;i<=t;++i){
printf("%ds:",s[nx][ny]+i+1);//这里打印的时候注意
printf("FIGHT AT (%d,%d)\n",x,y);
}
}
}
int main()
{
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
while(scanf("%d%d",&m,&n)!=EOF)
{
init();
for(int i=0;i<m;++i){
scanf("%s",g[i]);
}
bfs();
if(s[m-1][n-1]==-1)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",s[m-1][n-1]);
print(m-1,n-1);
}
printf("FINISH\n");
}
return 0;
}
优先队列的话,不用全部搜完,因为如果改点没有访问过,每次出队的肯定是时间最短的一个
#include <iostream>
#include <cstdio>
#include <memory.h>
#include<queue>
using namespace std;
const int maxn=105;
char g[maxn][maxn];
int dir[maxn][maxn];
int vis[maxn][maxn];
int n,m;
int dx[]={-1,1,0,0};
int dy[]={0,0,-1,1};
class node
{
public:
node(int _x,int _y,int _s):x(_x),y(_y),step(_s){}
bool friend operator < (const node &n1,const node &n2);
public:
int x,y,step;
};
void init()
{
memset(dir,-1,sizeof(dir));
memset(vis,-1,sizeof(vis));
vis[0][0]=0;
}
bool check(int x,int y)
{
if(x<0||y<0||x>=n||y>=m)return false;
if(g[x][y]=='X')return false;
if(vis[x][y]!=-1)return false;
return true;
}
bool operator < (const node &n1,const node &n2){
return n2.step<n1.step;
}
void bfs()
{
int newx,newy,news;
priority_queue<node>pq;
pq.push(node(0,0,0));
while(!pq.empty()){
node nd=pq.top();
pq.pop();
if(nd.x==n-1&&nd.y==m-1)return;//因为第一次搜到的肯定是时间最短的,找到就返回
for(int i=0;i<4;++i){
newx=nd.x+dx[i];
newy=nd.y+dy[i];
if(check(newx,newy)){
if(g[newx][newy]=='.'){
news=nd.step+1;
}
else{
news=nd.step+g[newx][newy]-'0'+1;
}
pq.push(node(newx,newy,news));
dir[newx][newy]=i;
vis[newx][newy]=news;
}
}
}
}
void print(int x,int y)
{
//cout<<x<<","<<y<<endl;
if(x==0&&y==0)return;
int prex=x-dx[dir[x][y]];
int prey=y-dy[dir[x][y]];
print(prex,prey);
printf("%ds:(%d,%d)->(%d,%d)\n",vis[prex][prey]+1,prex,prey,x,y);
if(g[x][y]!='.'){
int t=int(g[x][y]-'0');
for(int i=1;i<=t;++i){
printf("%ds:FIGHT AT (%d,%d)\n",vis[prex][prey]+i+1,x,y);
}
}
}
int main()
{
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
while(scanf("%d %d",&n,&m)!=EOF){
init();
for(int i=0;i<n;++i){
scanf("%s",g[i]);
}
bfs();
if(vis[n-1][m-1]==-1)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",vis[n-1][m-1]);
print(n-1,m-1);
}
printf("FINISH\n");
}
return 0;
}