http://acm.hdu.edu.cn/showproblem.php?pid=1242
题意:
    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;
}

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;
}

hdu1242 Rescue(BFS +优先队列 or BFS )的更多相关文章

  1. HDU 1242 -Rescue (双向BFS)&amp;&amp;( BFS+优先队列)

    题目链接:Rescue 进度落下的太多了,哎╮(╯▽╰)╭,渣渣我总是埋怨进度比别人慢...为什么不试着改变一下捏.... 開始以为是水题,想敲一下练手的,后来发现并非一个简单的搜索题,BFS做肯定出 ...

  2. UVA 11573 Ocean Currents --BFS+优先队列

    采用优先队列做BFS搜索,d[][]数组记录当前点到源点的距离,每次出队时选此时eng最小的出队,能保证最先到达的是eng最小的.而且后来用普通队列试了一下,超时..所以,能用优先队列的,就要用优先队 ...

  3. POJ 1724 ROADS(BFS+优先队列)

    题目链接 题意 : 求从1城市到n城市的最短路.但是每条路有两个属性,一个是路长,一个是花费.要求在花费为K内,找到最短路. 思路 :这个题好像有很多种做法,我用了BFS+优先队列.崔老师真是千年不变 ...

  4. hdu 1242 找到朋友最短的时间 (BFS+优先队列)

    找到朋友的最短时间 Sample Input7 8#.#####. //#不能走 a起点 x守卫 r朋友#.a#..r. //r可能不止一个#..#x.....#..#.##...##...#.... ...

  5. HDU 1428 漫步校园 (BFS+优先队列+记忆化搜索)

    题目地址:HDU 1428 先用BFS+优先队列求出全部点到机房的最短距离.然后用记忆化搜索去搜. 代码例如以下: #include <iostream> #include <str ...

  6. hdu1839(二分+优先队列,bfs+优先队列与spfa的区别)

    题意:有n个点,标号为点1到点n,每条路有两个属性,一个是经过经过这条路要的时间,一个是这条可以承受的容量.现在给出n个点,m条边,时间t:需要求在时间t的范围内,从点1到点n可以承受的最大容量... ...

  7. BFS+优先队列+状态压缩DP+TSP

    http://acm.hdu.edu.cn/showproblem.php?pid=4568 Hunter Time Limit: 2000/1000 MS (Java/Others)    Memo ...

  8. UVA-10603-Fill(BFS+优先队列)

    There are three jugs with a volume of a, b and c liters. (a, b, and c are positive integers not grea ...

  9. POJ - 2312 Battle City BFS+优先队列

    Battle City Many of us had played the game "Battle city" in our childhood, and some people ...

随机推荐

  1. [转]Restrict关键字

    0 定义 C99中新增加的用于修饰指针的关键字,用于表示该指针所指向的内存,只有通过该指针访问得到(如下ptr指向的内存单元只能通过ptr访问得到).从而可以让编译器对代码进行优化,生成更有效率的汇编 ...

  2. 洛谷 P4389: 付公主的背包

    题目传送门:洛谷 P4389. 题意简述: 有 \(n\) 个物品,每个物品都有无限多,第 \(i\) 个物品的体积为 \(v_i\)(\(v_i\le m\)). 问用这些物品恰好装满容量为 \(i ...

  3. 关于Mysql5.6半同步主从复制的开启方法【转】

    介绍 先了解一下mysql的主从复制是什么回事,我们都知道,mysql主从复制是基于binlog的复制方式,而mysql默认的主从复制方式,其实是异步复制. 主库实际上并不关心从库是否把数据拉完没有, ...

  4. mysql主从复制跳过复制错误【转】

    跳过复制错误 mysql因为binlog机制问题,有些时候会出现从库重放sql执行失败的情况,特别是旧的STATEMENT模式最容易出现这种情况(因为函数和存储过程等原因),这也是为什么强调使用mix ...

  5. poj1996

    多项式计算,有点像母函数,注意最后要判断最高次项是否为0. #include <cstdio> #include <cstring> using namespace std; ...

  6. urbuntu12.04 ftp服务器搭建

    1.安装ftp服务器: sudo apt-get install vsftpd 2..配置ftp 修改ftp的配置文件,该文件在/etc目录下,在终端中键入如下命令以打开配置文件: sudo vi / ...

  7. free命令中的buffer和cached的比较(转)

    原文链接:https://www.jianshu.com/p/cd2dd59d1566 最近在搞监控,突然看到我系统的内存要用完了,赶紧登录服务器看看, ~]# dstat -m     16G内存就 ...

  8. 【LeetCode】65. Valid Number

    Difficulty: Hard  More:[目录]LeetCode Java实现 Description Validate if a given string can be interpreted ...

  9. Unit的各种断言

    今天遇到这个问题,就值得自己总结一下. 1.介绍 JUnit为我们提供了一些辅助函数,他们用来帮助我们确定被测试的方法是否按照预期的效果正常工作,通常,把这些辅助函数称为断言.下面我们来介绍一下JUn ...

  10. s3fs挂s3作为本地盘制作ftp使用

    一. 安装s3fs 安装s3fs-fuserhttps://github.com/s3fs-fuse/s3fs-fuse 二. 安装vsftpd #查看当前系统版本cat /etc/redhat-re ...