Angel was caught by the MOLIGPY! He was put in prison by Moligpy. The prison is described as a N * M (N, M <= 200) matrix. There are WALLs, ROADs, and GUARDs in the prison.
Angel's friends want to save Angel. Their task is: approach Angel. We assume that "approach Angel" is to get to the position where Angel stays. When there's a guard in the grid, we must kill him (or her?) to move into the grid. We assume that we moving up, down, right, left takes us 1 unit time, and killing a guard takes 1 unit time, too. And we are strong enough to kill all the guards.
You have to calculate the minimal time to approach Angel. (We can move only UP, DOWN, LEFT and RIGHT, to the neighbor grid within bound, of course.)
Input
First line contains two integers stand for N and M.
Then N lines follows, every line has M characters. "." stands for road, "a" stands for Angel, and "r" stands for each of Angel's friend.
Process to the end of the file.
Output
For each test case, your program should output a single integer, standing for the minimal time needed. If such a number does no exist, you should output a line containing "Poor ANGEL has to stay in the prison all his life."
Sample Input
7 8
#.#####.
#.a#..r.
#..#x...
..#..#.#
#...##..
.#......
........
Sample Output
13
题目的意思应该很明确了,从r点出发,到达a点,要求求出到达a点的最小时间。如果经过的网格有守卫,则要杀死守卫,这样的话会多花一秒的时间。
又是迷宫问题,又是求最优解的问题,毫无疑问我们要用BFS来做。
vis数组保存了到达当前点所要花费的最小时间。
因为从起点到终点的路径不止一条,每次又要保证最终到达终点的这个路径是花费时间最短的,所以每次扩展一个点,如果从当前位置扩展之后的时间比当前扩展点的vis值大,也就是到达当前扩展点的时间比之前某步骤到达此扩展点的时间长,那么我们就不用扩展这个点,不用入队列,即不把他当做我们路径中的一部分。
用min1保存到达终点的最小值,初始化一个最大值,如果没有更新过,那么证明到达不了终点,即输出题目中不可能到达的情况。
代码如下:
先贴一个用DFS超时的代码:
//DFS// /* #include<stdio.h> #include<string.h> char map[220][220]; bool vis[220][220]; int x_move[4] = {-1, 0, 1, 0}; int y_move[4] = {0, 1, 0, -1}; int N,M; int s1,s2; int e1,e2; int min; int sign; int is_ok(int x,int y) { if(map[x][y]=='.'||map[x][y]=='x') return 1; else if(map[x][y]=='#') return 0; } void dfs(int s11,int s22,int count) { int tx,ty; int i,j,k; if(s11==e1&&s22==e2) { if(count<min) min=count; sign=1; return ; } for(i=0;i<4;i++) { tx=s11+x_move[i]; ty=s22+y_move[i]; if(tx<1||tx>N||ty<1||ty>M) //判断是否超出边界// continue ; if(vis[tx][ty]==0&&is_ok(tx,ty)) { vis[tx][ty]=1; if(map[tx][ty]=='x') count+=2; else count+=1; dfs(tx,ty,count); vis[tx][ty]=0; if(map[tx][ty]=='x') count-=2; else count-=1; } } return ; } int main() { //int min; int i,j,k; while(scanf("%d%d",&N,&M)!=EOF) { sign=0; min=9999999; getchar(); for(i=1;i<=N;i++) scanf("%s",map[i]+1); for(i=1;i<=N;i++) for(j=1;j<=M;j++) { if(map[i][j]=='r'){s1=i;s2=j;} if(map[i][j]=='a'){e1=i;e2=j;} } memset(vis,0,sizeof(vis)); vis[s1][s2]=1; dfs(s1,s2,0); if(sign==1) printf("%d\n",min); else printf("Poor ANGEL has to stay in the prison all his life.\n"); } return 0; }
BFS
#include<iostream> #include<queue> #include<limits.h> #include<stdio.h> using namespace std; typedef struct node { int x,y; int times; }node; queue<node> fuck; int N,M; int min1; char map[210][210]; int vis[210][210]; int x_move[4] = {-1, 0, 1, 0}; int y_move[4] = {0, 1, 0, -1}; int is_ok(int x,int y) { if(map[x][y]!='#') return 1; else return 0; } void BFS() { int i; node pos; node res; int tx,ty; while(!fuck.empty()) { pos=fuck.front(); fuck.pop(); res.x=pos.x; res.y=pos.y; res.times=pos.times; for(i=0;i<4;i++) { tx=res.x+x_move[i]; ty=res.y+y_move[i]; if(tx<1||tx>N||ty<1||ty>M) continue; if(is_ok(tx,ty)) { if(map[tx][ty]=='a') { min1=min1<res.times+1?min1:res.times+1; continue; } if(map[tx][ty]=='.'&&(res.times+1)<vis[tx][ty]) { vis[tx][ty]=res.times+1; pos.times=res.times+1; pos.x=tx; pos.y=ty; fuck.push(pos); } if(map[tx][ty]=='x'&&(res.times+2)<vis[tx][ty]) { vis[tx][ty]=res.times+2; pos.times=res.times+2; pos.x=tx; pos.y=ty; fuck.push(pos); } } } } } int main() { int i,j; node temp; while(scanf("%d%d",&N,&M)!=EOF) { for(i=1;i<=N;i++) for(j=1;j<=M;j++) vis[i][j]=INT_MAX; getchar(); for(i=1;i<=N;i++) { for(j=1;j<=M;j++) { scanf("%1c",&map[i][j]); if(map[i][j]=='r') { temp.x=i; temp.y=j; temp.times=0; fuck.push(temp); } } getchar(); } vis[temp.x][temp.y]=0; min1=INT_MAX; BFS(); if(min1==INT_MAX) printf("Poor ANGEL has to stay in the prison all his life.\n"); else printf("%d\n",min1); } return 0; }