hdu1242 Rescue(BFS +优先队列 or BFS )
题意:
Angel被传说中神秘的易做图的Moligpy人抓住了!他被关在一个迷宫中。迷宫的长、宽不超过200。 迷宫中有不可以越过的墙以及监狱的看守。
Angel的朋友带了一些救援队来到了迷宫中。他们的任务是:接近Angel。我们假设接近Angel就是到达Angel所在的位置。
假设移动需要1单位时间,杀死一个看守也需要1单位时间。到达一个格子以后,如果该格子有看守,则一定要杀死。交给你的任务是,最少要多少单位时间,才能到达Angel所在的地方?(只能向上、下、左、右4个方向移动)
Input
该题含有多组测试数据。每组测试数据第一行二个整数n,m。表示迷宫的大小为n*m (N, M <= 200) 。 以后n行,每行m个时字符。其中“#”代表墙,“.”表示可以移动,“x”表示看守,“a”表示Angel,“r”表示救援队伍。字母均为小写。
Output
一行,代表救出Angel的最短时间。如果救援小组永远不能达到Angel处,则输出“Poor ANGEL has to stay in the prison all his life.”
Sample Input
7 8
#.#####.
#.a#..r.
#..#x...
..#..#.#
#...##..
.#......
........
Sample Output
13
分析:
(N, M <= 200) 首先想到的是BFS, {P.S 有人dfs 0MS AC~~}
可能有多个’r’,而’a’只有一个,从’a’开始搜,找到的第一个’r’即为所求。
由于题目中增加了“x”表示看守这一个东东,经过“x”需要多耗一个单位时间。因此如果我们采用普通的宽搜,在第k层搜到了目标,但是耗时可能不止k个单位时间{有可能这条路径经过了“x”}。
对此我有三个想法:
1、采用优先队列(按到达该点的时候),这样就能保证最先扩展到目标状态的时候,耗时是最小的。
2、把当扩展到“x”点时,把他放到与他耗时一样的那一层。这样也能保证到扩展到目标状态时,耗时是最小的。
code1:(优先队列)
#include <iostream> #include <cstring> #include <cstdio> #include <queue> using namespace std; int n, m; char map[205][205]; int sx, sy; bool flag; struct node { int x, y, step; bool operator <(const node & t) const { return step>t.step; } }; int dx[]= {-1,0,0,1}; int dy[]= {0,-1,1,0}; void bfs() { node now, tmp; int i,xx,yy; priority_queue<node> q; now.x = sx, now.y = sy, now.step = 0; map[sx][sy] = '#'; q.push(now); while(!q.empty()) { now = q.top(); q.pop(); // cout<<now.x<<" "<<now.y<<" "<<now.step<<endl; for(i=0; i<4; i++) { xx = now.x +dx[i]; yy = now.y +dy[i]; if(xx<0||xx>=n||yy<0||yy>=m||map[xx][yy]=='#') continue; if(map[xx][yy]=='r') { cout<<now.step+1<<endl; flag = true; return ; } if(map[xx][yy]=='x') { tmp.x =xx, tmp.y = yy, tmp.step = now.step+2; q.push(tmp); } else { tmp.x =xx, tmp.y = yy, tmp.step = now.step+1; q.push(tmp); } map[xx][yy] = '#'; } } } int main() { int i, j; while(~scanf("%d%d",&n,&m)) { for(i=0; i<n; i++) for(j=0; j<m; j++) { cin>>map[i][j]; if(map[i][j]=='a') sx=i,sy=j; } flag = false; bfs(); if(!flag) printf("Poor ANGEL has to stay in the prison all his life.\n"); } return 0; } #include <iostream> #include <cstring> #include <cstdio> #include <queue> using namespace std; int n, m; char map[205][205]; int sx, sy; bool flag; struct node { int x, y, step; bool operator <(const node & t) const { return step>t.step; } }; int dx[]= {-1,0,0,1}; int dy[]= {0,-1,1,0}; void bfs() { node now, tmp; int i,xx,yy; priority_queue<node> q; now.x = sx, now.y = sy, now.step = 0; map[sx][sy] = '#'; q.push(now); while(!q.empty()) { now = q.top(); q.pop(); // cout<<now.x<<" "<<now.y<<" "<<now.step<<endl; for(i=0; i<4; i++) { xx = now.x +dx[i]; yy = now.y +dy[i]; if(xx<0||xx>=n||yy<0||yy>=m||map[xx][yy]=='#') continue; if(map[xx][yy]=='r') { cout<<now.step+1<<endl; flag = true; return ; } if(map[xx][yy]=='x') { tmp.x =xx, tmp.y = yy, tmp.step = now.step+2; q.push(tmp); } else { tmp.x =xx, tmp.y = yy, tmp.step = now.step+1; q.push(tmp); } map[xx][yy] = '#'; } } } int main() { int i, j; while(~scanf("%d%d",&n,&m)) { for(i=0; i<n; i++) for(j=0; j<m; j++) { cin>>map[i][j]; if(map[i][j]=='a') sx=i,sy=j; } flag = false; bfs(); if(!flag) printf("Poor ANGEL has to stay in the prison all his life.\n"); } return 0; }
code2:(想法2)
#include <iostream>
#include <queue>
#include <cstring>
using namespace std;
struct node
{
int x, y;
int step;
};
queue<node> q;
int N, M, prove, sx, sy, visit[202][202];
char map[202][202];
int dx[4] = {-1, 1, 0, 0};
int dy[4] = {0, 0, 1, -1,};
int check(int x, int y)
{
if(x < 0 || x >= N || y < 0 || y >= M)
return 0;
else
return 1;
}
void BFS()
{
while(!q.empty())
q.pop();
node s, e;
memset(visit, 0, sizeof(visit));
s.step = 0; s.x = sx; s.y = sy;
q.push(s);
visit[s.x][s.y] = 1;
while(!q.empty())
{
s = q.front();
q.pop();
if(map[s.x][s.y] == 'a')
{
cout << s.step << endl;
prove =1;
}
//如取出的是在有警卫的格子中,即杀掉警卫再次进入队列
if(map[s.x][s.y] == 'x')
{
map[s.x][s.y] = '.';
s.step += 1;
q.push(s);
continue;
}
for(int i = 0; i < 4; i++)
{
e.x = s.x + dx[i]; e.y = s.y + dy[i];
if(!check(e.x, e.y) || visit[e.x][e.y]
|| map[e.x][e.y] == '#')
continue;
e.step = s.step + 1;
q.push(e);
visit[e.x][e.y] = 1;
}
}
}
int main()
{
while(cin >> N >> M)
{
for(int i = 0; i < N; i++)
for(int j = 0; j < M; j++)
{
cin >> map[i][j];
if(map[i][j] == 'r')
{ sx = i; sy = j; }
}
prove = 0;
BFS();
if(!prove)
cout << "Poor ANGEL has to stay in the prison all his life." << endl;
}
return 0;
}
#include <iostream>
#include <queue>
#include <cstring>
using namespace std;
struct node
{
int x, y;
int step;
};
queue<node> q;
int N, M, prove, sx, sy, visit[202][202];
char map[202][202];
int dx[4] = {-1, 1, 0, 0};
int dy[4] = {0, 0, 1, -1,};
int check(int x, int y)
{
if(x < 0 || x >= N || y &补充:软件开发 , C++ ,