题目链接: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. [转]application windows are expected to have a root view controller错误

    转载地址:http://blog.sina.com.cn/s/blog_6784e6ea01017jfy.html 最新更正:这个提示几乎不影响编译和运行,可以不用设置.     产生这个提示的操作: ...

  2. [转]Linq中GroupBy方法的使用总结

    Demo模型类: public class StudentScore { public int ID { set; get; } public string Name { set; get; } pu ...

  3. UVA 12050 - Palindrome Numbers 模拟

    题目大意:给出i,输出第i个镜像数,不能有前导0. 题解:从外层开始模拟 #include <stdio.h> int p(int x) { int sum, i; ;i<=x;i+ ...

  4. ViewController之间的切换动画

    一 .API介绍 iOS7开始,苹果推出了自定义转场动画API.从此,任何可以用Core Animation实现的动画,都可以出现在两个ViewController的切换之间 知识点图: 从上图可以看 ...

  5. 修改客户端Webbrowser对应IE版本步骤

    制作注册表文件的过程 1,” HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\InternetExplorer\MAIN\ FeatureControl\FEATURE_B ...

  6. 循环,range,continue 和 break

    1.for循环 用户按照顺序循环可迭代对象中的内容, PS:break.continue li = [11,22,33,44] for item in li:     print item 2.enu ...

  7. MSM8909+Android5.1.1之系统烧录

    1.     安装高通USB驱动 图1 安装成功后,同时按下设备的音量+和音量-按键,且用USB连接到设备上,在设"设备管理器--->端口"下面看到USB虚拟的端口,如下: ...

  8. Native SQL

    声明:原创作品,转载时请注明文章来自SAP师太技术博客( 博/客/园www.cnblogs.com):www.cnblogs.com/jiangzhengjun,并以超链接形式标明文章原始出处,否则将 ...

  9. C语言文法定义与C程序的推导过程

    program à external_declaration | program external_declaration <程序> ->  <外部声明> |  < ...

  10. hdu 3018 Ant Trip 欧拉回路+并查集

    Ant Trip Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Problem ...