以前曾经做过每一步都是平等的bfs 今天的这一题让我开阔了视野
因为上一步和下一步所花费的时间可能不同
下一步的来源可以分为两种情况 1 来自时间短的 2 来自时间长的
因此我们必须有一个选择的过程 这就需要一个记忆化数组 用来保存当前格的最少时间
犯了memset 的错误 memset 是一个字节一个字节初始化的 显然不对
其他的都和hero in maze 一样 是一个很老实的广搜
从这里我认为 其实是广搜被扩展了 。。。
好题 赞一个!
#include <iostream>
#include <string.h>
#include <queue>
using namespace std;
typedef struct Node
{
int x;
int y;
int step;
}Node;
int dx[4]={0,1,0,-1};
int dy[4]={1,0,-1,0};
bool visited[202][202];
int dp[202][202]; //记忆化dp数组的建立
char map[202][202];
int m,n;
bool inmap(int x,int y)
{
return x>=0&&x<m&&y>=0&&y<n;
}
int min(int x,int y)
{
if(x<y)return x;
else return y;
}
int minstep=0x7fffffff;
void bfs(int x,int y)
{
//
queue<Node>q;
Node p;
p.x=x;
p.y=y;
p.step=0;//初始化
q.push(p);
while(!q.empty())
{
p=q.front();
q.pop();
int i;
for(i=0;i<4;i++)
{
Node temp;
temp.x=p.x+dx[i];
temp.y=p.y+dy[i];
if(map[temp.x][temp.y]!='#' && inmap(temp.x,temp.y))/// 并非像visited那么简单 这里需要的是一种记忆化搜索 或者说这里其实是使用了一种动态规划 因为上一次搜到的状态与下一次相关
{
if(p.step+1<dp[temp.x][temp.y])
{
dp[temp.x][temp.y]=p.step+1;
temp.step=p.step+1;
if(map[temp.x][temp.y]=='x')
temp.step++;
// cout<<"dddddd"<<endl;
if(map[temp.x][temp.y]=='r')
minstep=min(temp.step,minstep);///注意到因为朋友会有不止一个 可以先找出朋友的个数 但是这也可能是访问到的同一个朋友 所以需要的是访问到朋友的最小步数
// cout<<temp.x<<" "<<temp.y<<endl;
q.push(temp);
}
}
}
}
}
int main()
{
while(cin>>m>>n)
{
int i,j,c,d;
for(i=0;i<m;i++)
for(j=0;j<n;j++)
{
cin>>map[i][j];
if(map[i][j]=='a')
{
c=i;
d=j;
}
dp[i][j]=0x7fffffff;
}
// cout<<c<<" "<<d<<endl;
bfs(c,d);
if(minstep!=0x7fffffff)
cout<<minstep<<endl;
else
cout<<"Poor ANGEL has to stay in the prison all his life."<<endl;
minstep=0x7fffffff;
}
return 0;
}