题目:
Rescue
**Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 27885 Accepted Submission(s): 9858
**
\
Problem Description
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
\
Author
CHEN, Xue
\
Source
代码1(错误,虽然可以AC):
此代码是从r点搜到a点,但是题目中的是'r'点有多个,'a'点只有一个,此代码只是默认'r'只有一个进行搜索,所以这道题的后台数据有问题,这道题的后台数据只有一个'r'
#include <stdio.h>
#include <queue>
#include <string.h>
#include <algorithm>
#define mem(a,b) memset(a,b,sizeof(a))
using namespace std;
int go[4][2]= {{1,0},{-1,0},{0,1},{0,-1}};//上下左右四个方向
char map[210][210];//地图
int vis[210][210];//标记数组
int x1,y1,x2,y2;
int n,m;
struct node
{
int x,y,step;
friend bool operator < (node a,node b)//重载运算符
{
return a.step>b.step;//让步数按照从小到大来排列
}
};
int bfs(int x,int y)
{
node now,to;//现在的状态和要到达的状态
now.x=x,now.y=y,now.step=0;//当前的步数为0
priority_queue<node>q;//定义优先队列
q.push(now);
vis[x][y]=1;//把走过的标记为1
while(!q.empty())
{
now=q.top();
if(now.x==x2&&now.y==y2)return now.step;//满足条件返回步数
q.pop();
for(int i=0; i<4; i++)
{
int xx=now.x+go[i][0];
int yy=now.y+go[i][1];
if(xx>=0&&xx<n&&yy>=0&&yy<m&&vis[xx][yy]==0&&map[xx][yy]!='#')//判断是否越界
{
to.x=xx;
to.y=yy;
to.step=now.step+1;
if(map[to.x][to.y]=='x')//碰到士兵步数+1
to.step++;
vis[to.x][to.y]=1;//走过的标记为1
q.push(to);
}
}
}
return 0;//走不到目的地返回0
}
int main()
{
while(~scanf("%d%d",&n,&m))
{
for(int i=0; i<n; i++)
{
scanf("%s",map[i]);
for(int j=0; j<m; j++)
{
if(map[i][j]=='r')//起点
{
x1=i;
y1=j;
}
else if(map[i][j]=='a')//终点
{
x2=i;
y2=j;
}
}
}
mem(vis,0);//没有走过的标记为0
int aa=bfs(x1,y1);
if(aa)
printf("%d\n",aa);
else
printf("Poor ANGEL has to stay in the prison all his life.\n");
}
return 0;
}
代码2(正确):
此代码是从终点'a'开始搜索搜索到一个最近的起点‘r’
#include <stdio.h>
#include <queue>
#include <string.h>
#include <algorithm>
#define mem(a,b) memset(a,b,sizeof(a))
using namespace std;
int go[4][2]= {{1,0},{-1,0},{0,1},{0,-1}};//上下左右四个方向
char map[210][210];//地图
int vis[210][210];//标记数组
int x1,y1;
int n,m;
struct node
{
int x,y,step;
friend bool operator < (node a,node b)//重载运算符
{
return a.step>b.step;//让步数按照从小到大来排列
}
};
int bfs(int x,int y)
{
node now,to;//现在的状态和要到达的状态
now.x=x,now.y=y,now.step=0;//当前的步数为0
priority_queue<node>q;//定义优先队列
q.push(now);
vis[x][y]=1;//把走过的标记为1
while(!q.empty())
{
now=q.top();
if(map[now.x][now.y]=='r')return now.step;//满足条件返回步数
q.pop();
for(int i=0; i<4; i++)
{
int xx=now.x+go[i][0];
int yy=now.y+go[i][1];
if(xx>=0&&xx<n&&yy>=0&&yy<m&&vis[xx][yy]==0&&map[xx][yy]!='#')//判断是否越界
{
to.x=xx;
to.y=yy;
to.step=now.step+1;
if(map[to.x][to.y]=='x')//碰到士兵步数+1
to.step++;
vis[to.x][to.y]=1;//走过的标记为1
q.push(to);
}
}
}
return 0;//走不到目的地返回0
}
int main()
{
while(~scanf("%d%d",&n,&m))
{
for(int i=0; i<n; i++)
{
scanf("%s",map[i]);
for(int j=0; j<m; j++)
{
if(map[i][j]=='a')//终点
{
x1=i;
y1=j;
}
}
}
mem(vis,0);//没有走过的标记为0
int aa=bfs(x1,y1);
if(aa)
printf("%d\n",aa);
else
printf("Poor ANGEL has to stay in the prison all his life.\n");
}
return 0;
}
这个代码对代码1进行了改进,从终点天使开始搜,搜到离他最近的一个朋友就返回步数
\
\
\