题目大意: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){//当遇到' '的时候循环结束 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. "); }else{ printf("%d ",ans); } } }