您的位置:首页 > 产品设计 > UI/UE

BFS 搜索 Problem 1012 Rescue 拯救天使

2016-04-23 20:48 316 查看


Problem ID:1012 Rescue

简单题意:给出一个地图,其中有一个"a",代表angle,若干个"r",代表去营救angle的朋友,"x"标志敌人,"."标志可以行进的区域,"#"标志不可行进的区域。只可直行,不能斜向前进。走向"."耗时1,走向并击败"x"耗时2,求能拯救angle所需要的最短时间。如不能拯救,则输出"Poor
ANGEL has to stay in the prison all his life."

解题思路形成过程:利用BFS,但所有能经过的区域都要搜索一遍(这是重点),因为"."区域和"x"区域耗时不同。

用一个二维数组记录能到达每个区域的最短时间。

在遍历过程中,如果按照某走法将要到达的某区域的所花费的总时间比之前记录的要大,则不走,从而进行剪枝。

感想:因为是所有"."和"x"区域都要遍历一遍,用DFS也可以。一开始没有考虑到这个条件,WA了一次,还是考虑的不够细致。



代码:

#include<iostream>
#include<stdio.h>
#include<string.h>
#include<queue>
using namespace std;
int cmap[201][201],mark[201][201];
int r1[201],r2[201];
int dir[4][2]={{-1,0},{0,-1},{0,1},{1,0}};
int aim_r,aim_c;
int n,m;
void bfs(int r,int c)
{
queue<int>s;
s.push(r);
s.push(c);
s.push(0);
mark[r][c]=0;
while(!s.empty())
{
int now_r=s.front();
s.pop();
int now_c=s.front();
s.pop();
int now_cnt=s.front();
s.pop();
for(int i=0;i<4;++i){
int temp_r=now_r;
int temp_c=now_c;
int temp_cnt=now_cnt;
temp_r+=dir[i][0];
temp_c+=dir[i][1];
if(cmap[temp_r][temp_c]==3)
temp_cnt+=2;
else
temp_cnt++;
if(temp_r>=0&&temp_r<n&&temp_c>=0&&temp_c<m)
if(cmap[temp_r][temp_c]!=1&&cmap[temp_r][temp_c]!=5)
if(mark[temp_r][temp_c]>temp_cnt||mark[temp_r][temp_c]==-1)//所有"."和"x"区域必须全部搜索一遍.
{

s.push(temp_r);
s.push(temp_c);
s.push(temp_cnt);
mark[temp_r][temp_c]=temp_cnt;
}
}
}
}
int main()
{
// freopen("2.txt","r",stdin);
while(scanf("%d%d",&n,&m)!=EOF)
{
memset(mark,-1,sizeof(mark));
int t=0;
for(int i=0;i<n;++i)
for(int j=0;j<m;++j){
char temp;
cin>>temp;
if(temp=='r'){
cmap[i][j]=1;
r1[t]=i;
r2[t]=j;
++t;
}
else if(temp=='a'){
cmap[i][j]=2;
aim_r=i;
aim_c=j;
}
else if(temp=='x')
cmap[i][j]=3;
else if(temp=='.')        //可不写
cmap[i][j]=4;
else if(temp=='#')
cmap[i][j]=5;
}
for(int i=0;i<t;++i)
bfs(r1[i],r2[i]);
int cmin=mark[aim_r][aim_c];
if(cmin!=-1)
printf("%d\n",cmin);
else
printf("Poor ANGEL has to stay in the prison all his life.\n");
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: