原题链接:
http://acm.hdu.edu.cn/showproblem.php?pid=1242
题目大意:
‘a’到‘r’所需最少时间。‘#’墙,‘x’花费两个时间,‘.’花费一个时间。
由于‘x'与’.‘的时间不一样,所以不能直接bfs,要用优先队列排下序。
BFS法更快
方法一:
代码如下:
#include<iostream>
#include<cstdio>
#include<queue>
#include<cstring>
using namespace std;
const int MAXN=200+10;
char G[MAXN][MAXN];
bool vis[MAXN][MAXN];
int n,m;
const int nextx[]={-1,0,1,0};
const int nexty[]={0,-1,0,1};
int ans;
struct Node
{
int x,y;
int time;
friend bool operator <(const Node &x,const Node &y)
{
return x.time>y.time;
}
Node(){}
Node(int x,int y,int time):x(x),y(y),time(time){}
};
Node be;
bool check(int nx,int ny)
{
return (nx>=0&&nx<n&&ny>=0&&ny<m&&!(vis[nx][ny])&&G[nx][ny]!='#');//条件为 不出棋盘,未遍历过,不是墙
}
int BFS()
{
memset(vis,0,sizeof(vis));
priority_queue<Node>q;
q.push(be);
vis[be.x][be.y]=true;
Node now;
while(!(q.empty()))
{
now=q.top();
q.pop();
if(G[now.x][now.y]=='r')//最少时间
return now.time;
for(int i=0;i<4;i++)
{
int nx=now.x+nextx[i];
int ny=now.y+nexty[i];
if(check(nx,ny))
{
vis[nx][ny]=true;
if(G[nx][ny]=='x')
{
Node temp(nx,ny,now.time+2);
q.push(temp);
}
else
{
Node temp(nx,ny,now.time+1);
q.push(temp);
}
}
}
}
return -1;
}
int main()
{
while(scanf("%d%d",&n,&m)!=EOF)
{
getchar();//读掉 \n
for(int i=0;i<n;i++)
{
for(int j=0;j<m;j++)
{
scanf("%c",&G[i][j]);
//cin>>G[i][j];
if(G[i][j]=='a')
{
be.x=i;
be.y=j;
be.time=0;
}
}
getchar();
}
ans=BFS();
if(ans!=-1)
cout<<ans<<endl;
else cout<<"Poor ANGEL has to stay in the prison all his life."<<endl;
}
return 0;
}
方法二:
代码如下:
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int MAXN=200+10;
int n,m,ans;
char G[MAXN][MAXN];
bool vis[MAXN][MAXN];
const int nextx[]={-1,0,1,0};
const int nexty[]={0,-1,0,1};
void DFS(int x,int y,int dis)
{
if(dis>=ans)return;//时间已大于当前最优时间
if(!(x>=0&&x<n&&y>=0&&y<m))return;//出棋盘
if(G[x][y]=='#'||vis[x][y])return;//访问过,是墙
if(G[x][y]=='r')
{
if(dis<ans)
ans=dis;
return;
}
vis[x][y]=true;
if(G[x][y]=='x')dis+=2;
else dis++;
for(int i=0;i<4;i++)
DFS(x+nextx[i],y+nexty[i],dis);
vis[x][y]=false;//当该路不是正确答案时,需要释放该路
return;
}
int main()
{
while(scanf("%d%d%*c",&n,&m)!=EOF)
{
memset(vis,0,sizeof(vis));
int bx,by;
ans=MAXN*MAXN*2;
for(int i=0;i<n;i++)
{
for(int j=0;j<m;j++)
{
scanf("%c",&G[i][j]);
if(G[i][j]=='a')
{
bx=i;by=j;
}
}
getchar();
}
DFS(bx,by,0);
if(ans==MAXN*MAXN*2)cout<<"Poor ANGEL has to stay in the prison all his life." <<endl;
else cout<<ans<<endl;
}
return 0;
}