题目大意:friends用最短的时间去救angel '.'表示通道 '#'表示墙壁 'x'表示guard.走一格要一单位时间,杀死一个guard要一个单位时间.
如果可以救求最短时间,否则按要求输出
解题思路:BFS
1)其实这一题主要是对BFS种的标记数组visited[][]。如果路上只有两种情况如:路、墙壁。那么用这种数组就足够了(它用来标记访问过还是没有访问过。其实,我们可以这样理解,当我们访问过以后,我们就把访问过的点理解墙壁——不可访问。。)。但是如果对于那种路上存在多种情形的情况,我们在使用visited[][]来标记的话,那么,可能就不那么方便了(因为 bool数组的返回值只有两种情况)。这是我们可以定义一个map[][]作为对visited数组的扩充。。。。用来标记路上可能遇到的各种情况。
代码如下:
/*
* 1242_3.cpp
*
* Created on: 2013年8月16日
* Author: Administrator
* 我喜欢章泽天。。。。。。
*/
#include <iostream>
#include <queue>
using namespace std;
/**
* n : 用来记录行数
* m : 用来记录列数
* x_e,y_e :用来记录结束位置
* x_s,y_s :用来记录开始位置
*/
int n,m;
int x_e,y_e;
int x_s,y_s;
//map[201][201]:用来存储可能遇到的各种情况
int map[201][201];
int dir[4][2]={{0,1},{0,-1},{1,0},{-1,0}};
struct State{
int x;
int y;
int step_counter;
};
bool checkState(State st){
if(map[st.x][st.y] == 1 || st.x < 0 || st.x >= n || st.y < 0 || st.y >= m ){
return true;
}
return false;
}
int bfs(){
queue<State> q;
State st,now,next;
st.x = x_s;
st.y = y_s;
st.step_counter = 0;
q.push(st);
map[st.x][st.y] = 1;
while(!q.empty()){
now = q.front();
if(now.x == x_e && now.y == y_e){
return now.step_counter;
}
int i;
for(i = 0 ; i < 4 ; ++i){
next.x = now.x + dir[i][0];
next.y = now.y + dir[i][1];
if(checkState(next)){//排除了墙壁以及越界的情况
continue;
}
if(map[next.x][next.y] == -1){//处理碰到的是敌人的情况
next.step_counter = now.step_counter + 2;
}else{//处理是道路的情况
next.step_counter = now.step_counter + 1;
}
q.push(next);
map[next.x][next.y] = 1;
}
q.pop();
}
return -1;
}
int main(){
while(scanf("%d%d",&n,&m)!=EOF){
memset(map,0,sizeof(map));
int i,j;
char str[205];
for( i = 0 ; i < n ; ++i){
scanf("%s",str);//注意这种写法
for(j = 0 ; str[j] ; ++j){//当遇到'\0'的时候循环结束
if(str[j] == 'r'){
x_s = i;
y_s = j;
}else if(str[j] == 'a'){
x_e = i;
y_e = j;
}else if(str[j] == '.'){
map[i][j] = 0;
}else if(str[j] == '#'){
map[i][j] = 1;
}else if(str[j] == 'x'){
map[i][j] = -1;
}
}
}
int ans = bfs();
if(ans == -1){
printf("Poor ANGEL has to stay in the prison all his life.\n");
}else{
printf("%d\n",ans);
}
}
}