题目链接:hdu 1242

  这题也是迷宫类搜索,题意说的是 'a' 表示被拯救的人,'r' 表示搜救者(注意可能有多个),'.' 表示道路(耗费一单位时间通过),'#' 表示墙壁,'x' 代表警卫(耗费两个单位时间通过),然后求出 'r' 能找到 'a' 的最短时间,找不到输出 "…………"(竟然在这里也 wa 了一发 -.-||)。很明显是广搜了,因为 'r' 可能有多个,所以我们反过来从 'a' 开始搜,每次搜到 'r' 都更新最小时间值(很重要的一个转换!)。可是这题因为通过 'x' 需要 2 单位时间导致结点间的变化不一致,所以不能用简单的队列(等下会否定这个说法),需要用优先队列,再加上 bfs 就行。

 #include<cstdio>
#include<cstring>
#include<cstdlib>
#include<queue>
#include<algorithm>
using namespace std;
#define For(i,s,t) for(int i=s; i<t; ++i)
const int inf= 0x2fffffff; int n,m;
char s[][];
int dir[][]= {{-,},{,-},{,},{,}}; struct node{
int x,y,t;
node(int x=, int y=, int t= inf): x(x),y(y),t(t) {}
bool operator < (const node &n2) const {
return t > n2.t;
}
}; int main(){
int si,sj;
while(~scanf("%d%d",&n,&m)){
getchar();
For(i,,n+) For(j,,m+) s[i][j]= '#';
for(int i=; i<=n; ++i,getchar())
For(j,,m+) if((s[i][j]= getchar())=='a') si=i, sj= j; int ans= ;
priority_queue<node> q;
q.push(node(si,sj,));
s[si][sj]= '#';
while(q.size()){
node p= q.top(); q.pop();
For(k,,){
int dx= p.x+dir[k][], dy= p.y+dir[k][];
if(s[dx][dy]!='#'){
q.push(node(dx,dy,(s[dx][dy]=='x'? p.t+: p.t+)));
if(s[dx][dy]=='r') ans= min(ans,p.t+);
s[dx][dy]= '#';
}
}
}
if(ans==) puts("Poor ANGEL has to stay in the prison all his life.");
else printf("%d\n",ans);
}
return ;
}

  这一句 " if(s[dx][dy]=='r') ans= min(ans,p.t+1); " 对 'r' 的访问和更新需要很注意位置,一定要放在 " s[dx][dy]= '#'; " 即对已访问结点做标记之前,否则 ans 的值不会变的。

  上面是优先队列+bfs,然后这题实际上还可以用加了特技的普通队列来实现 bfs。怎么做呢,仔细观察这题每两个结点间的(边)权值实际上只有两种:1和2。2对应的就是 'x' 这个结点,只要做特殊处理就行:把它一分为二,分成两个结点 'y' 和 '.' 。大体步骤是:对每个出队的结点访问它的后继结点,当为 'x' 时,把它标记为 'y',和其它结点一样边权值+1入队,如果为 'y',那么就直接跳过,因为 'y' 本来就是从 'x' 转化过来的,并非从它旁边的结点扩展过来;这样的话,每次从队首出对的结点就只有两种可能:'y' 和 '#'(对于 '.' 和 'r' 入队后做的标记),如果是 'y' 的话,就把结点权值+1 再次进队(因为 'x' 本来就耗时 2),然后该结点才真正标记为 '#' 表示确实地访问完,这样的话就能用普通的队列来实现 bfs了,主要就是把那些权值不一致的结点通过拆分成多个等价的结点以转化为权值一致的图。

 #include<cstdio>
#include<cstring>
#include<cstdlib>
#include<queue>
#include<algorithm>
using namespace std;
#define For(i,s,t) for(int i=s; i<t; ++i)
const int inf= 0x2fffffff; int n,m;
char s[][];
int dir[][]= {{-,},{,-},{,},{,}}; struct node{
int x,y,t;
node(int x=, int y=, int t= inf): x(x),y(y),t(t) {}
}; int main(){
int si,sj;
while(~scanf("%d%d",&n,&m)){
getchar();
For(i,,n+) For(j,,m+) s[i][j]= '#';
for(int i=; i<=n; ++i,getchar())
For(j,,m+) if((s[i][j]= getchar())=='a') si=i, sj= j; int ans= ;
queue<node> q;
q.push(node(si,sj,));
s[si][sj]= '#';
while(q.size()){
node p= q.front(); q.pop();
if(s[p.x][p.y]=='y'){
q.push(node(p.x,p.y,p.t+));
s[p.x][p.y]= '#';
continue;
}
For(k,,){
int dx= p.x+dir[k][], dy= p.y+dir[k][];
if(s[dx][dy]=='y') continue;
if(s[dx][dy]!='#'){
q.push(node(dx,dy,p.t+));
if(s[dx][dy]=='x') {
s[dx][dy]= 'y';
continue;
}
if(s[dx][dy]=='r') ans= min(ans,p.t+);
s[dx][dy]= '#';
}
}
}
if(ans==) puts("Poor ANGEL has to stay in the prison all his life.");
else printf("%d\n",ans);
}
return ;
}

  当然,这个如此巧妙的方法是从叉姐那儿听说过来的,我不过尝试着把它实现了而已,只能膜拜那些 OI 大神了 Orz ~~

  另外,很奇怪的是,这题居然也能用 dfs 来做:

 #include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
using namespace std;
#define For(i,s,t) for(int i=s; i<t; ++i)
const int maxn= +; char ch[maxn][maxn];
int dir[][]= {{-,,,},{,-,,}};
int Min, num; void dfs(int i, int j, int len)
{
++num;
if(ch[i][j]=='#') return ;
if(ch[i][j]=='x') ++len;
if(len > Min) return ;
if(ch[i][j]=='r'){
Min= min(Min,len);
return ;
}
char c= ch[i][j];
ch[i][j]= '#';
For(k,,) {
int dx= i+dir[][k], dy= j+dir[][k];
dfs(dx,dy,len+);
}
ch[i][j]= c;
} int main()
{
int n,m,si,sj;
while(~scanf("%d%d",&n,&m))
{
getchar();
memset(ch,'#',sizeof(ch));
for(int i=; i<=n; ++i,getchar())
For(j,,m+) if((ch[i][j]= getchar())=='a') si= i, sj=j; Min= ;
dfs(si,sj,);
if(Min==) puts("Poor ANGEL has to stay in the prison all his life.");
else printf("%d\n",Min);
}
return ;
}

  对于这样的题来说 dfs 应该很容易超时才对,可是实际上和 bfs 相差无几,只能再一次吐槽下杭电数据的弱了,anyway,我还是会继续被 HDOJ 虐……

hdu 1242 Rescue的更多相关文章

  1. hdu - 1242 Rescue && hdu - 2425 Hiking Trip (优先队列+bfs)

    http://acm.hdu.edu.cn/showproblem.php?pid=1242 感觉题目没有表述清楚,angel的朋友应该不一定只有一个,那么正解就是a去搜索r,再用普通的bfs就能过了 ...

  2. hdu 1242 Rescue(bfs)

    此刻再看优先队列,不像刚接触时的那般迷茫!这也许就是集训的成果吧! 加油!!!优先队列必须要搞定的! 这道题意很简单!自己定义优先级别! +++++++++++++++++++++++++++++++ ...

  3. 杭电 HDU 1242 Rescue

    http://acm.hdu.edu.cn/showproblem.php?pid=1242 问题:牢房里有墙(#),警卫(x)和道路( . ),天使被关在牢房里位置为a,你的位置在r处,杀死一个警卫 ...

  4. HDU 1242 Rescue(优先队列)

    题目来源: http://acm.hdu.edu.cn/showproblem.php?pid=1242 题目描述: Problem Description   Angel was caught by ...

  5. HDU 1242 Rescue(BFS+优先队列)

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1242 题目描述: Problem Description Angel was caught by t ...

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

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

  7. hdu 1242:Rescue(BFS广搜 + 优先队列)

    Rescue Time Limit : 2000/1000ms (Java/Other)   Memory Limit : 65536/32768K (Java/Other) Total Submis ...

  8. HDU 1242 Rescue (BFS(广度优先搜索))

    Rescue Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submis ...

  9. HDU 1242 Rescue(BFS),ZOJ 1649

    题目链接 ZOJ链接 Problem Description Angel was caught by the MOLIGPY! He was put in prison by Moligpy. The ...

随机推荐

  1. 进程外session

    进程外session A  SqlServer 1.管理员身份运行cmd 2.更换目录  cd c:\Windows\Microsoft.NET\Framework\v4.0.30319> 3. ...

  2. Netfilter/iptables防火墙

    http://os.51cto.com/art/201107/273443.htm [51CTO独家特稿]Linux系统管理员们都接触过Netfilter/iptables,这是Linux系统自带的免 ...

  3. MySQL bin-log 日志清理方式

    MySQL bin-log 作用   1.数据恢复:如果你的数据库出问题了,而你之前有过备份,那么可以看日志文件,找出是哪个命令导致你的数据库出问题了,想办法挽回损失. 2.主从服务器之间同步数据:主 ...

  4. CSS之盒子模型

    CSS核心内容 源文件目录: D:\Users\ylf\Workspaces\MyEclipse 10 标准流 盒子模型 浮动 定位 标准流/非标准流: 标准流:就是普通的 非标准流:实际工作中要打破 ...

  5. 2016 Al-Baath University Training Camp Contest-1 B

    Description A group of junior programmers are attending an advanced programming camp, where they lea ...

  6. js的Prototype属性 解释及常用方法

    函数:原型 每一个构造函数都有一个属性叫做原型(prototype,下面都不再翻译,使用其原文).这个属性非常有用:为一个特定类声明通用的变量或者函数. prototype的定义 你不需要显式地声明一 ...

  7. 【Java】Java原生的序列化和反序列化

    写一个Java原生的序列化和反序列化的DEMO. 需序列化的类: package com.nicchagil.nativeserialize; import java.io.Serializable; ...

  8. Python3基础 print与,结合 一次输出多个数据

    镇场诗:---大梦谁觉,水月中建博客.百千磨难,才知世事无常.---今持佛语,技术无量愿学.愿尽所学,铸一良心博客.------------------------------------------ ...

  9. Oracle中如何使用REGEXP_SUBSTR函数

    REGEXP_SUBSTR函数格式如下: function REGEXP_SUBSTR(String, pattern, position, occurrence, modifier) __srcst ...

  10. 无缝漫游 Seamless Roaming

    点击打开链接 如你在由一个以上AP组成的Wifi 无线网中,拿著一部WindowXP 笔记本电脑,乘著汽车在Wifi网中往来,不断通过无线卡Ping 一个目標,你会发现在无线卡过站时,掉包可以高达半分 ...