hdu 1242 Rescue

时间:2022-09-06 07:59:37

  题目链接: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 * 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 * 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 * all his life.");
else printf("%d\n",Min);
}
return ;
}

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

hdu 1242 Rescue的更多相关文章

  1. hdu - 1242 Rescue &amp&semi;&amp&semi; hdu - 2425 Hiking Trip &lpar;优先队列&plus;bfs&rpar;

    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&lpar;BFS&plus;优先队列&rpar;

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

  6. HDU 1242 -Rescue &lpar;双向BFS)&amp&semi;amp&semi;&amp&semi;amp&semi;( BFS&plus;优先队列&rpar;

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

  7. hdu 1242&colon;Rescue(BFS广搜 &plus; 优先队列)

    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&lpar;BFS&rpar;,ZOJ 1649

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

随机推荐

  1. Mongodb 语法&comma;update&comma;insert&comma;delete&comma;find

    ---恢复内容开始--- db.Users.update({OrganizationCode:"Global"},{$set:{OrganizationCode:"Fre ...

  2. Silverlight Visifire控件 &period;net后台控制aspx页面控件的显示与隐藏,动态给控件赋值,选定默认值的设定

    .net后台代码: 控件的显示与隐藏: this.dateStart.Visibility = Visibility.Collapsed;//不显示控件 this.dateYear.Visibilit ...

  3. error while loading shared libraries&colon; libpthread&period;so&period;0&colon; cannot open shared object file&colon; No such file

    安装rac10g,出现例如以下错误: [root@rac2 oracle]# /u01/product/crs/root.sh WARNING: directory '/u01/product' is ...

  4. JavaScript编写连连看

    这几天写题比较少,做了一下网页设计的期末大作业.搞了个连连看,核心代码和hdu 1175那个题目一样. 越来越觉得学ACM是十分有用的,软件的核心是数据结构和算法,学会了DFS,连连看就水到渠成了. ...

  5. ubuntu16&period;04 HyperLedger Fabric 1&period;2&period;0 开发环境搭建

    安装准备 1. 安装git.cRUL.gcc/g++和make $ sudo apt-get update $ sudo apt-get install build-essential git cur ...

  6. MariaDB 服务器在 MySQL Workbench 备份数据的时候出错如何解决

    服务器是运行在 MariaDB 10.2 上面的,在使用 MySQL Workbench 出现错误: mysqldump: Couldn't execute 'SELECT COLUMN_NAME, ...

  7. python基础之字符串格式化

    python中字符串格式化有两种,一种是%,另一种是str中的format()功能. % 列举格式符 %s    字符串 %c    单个字符 %b    二进制整数 %d    十进制整数 %i   ...

  8. Tarjan的强连通分量算法

    Tarjan算法用于寻找图G(V,E)中的所有强连通分量,其时间复杂度为O(|V|+|E|). 所谓强连通分量就是V的某个极大子集,其中任意两个结点u,v在图中都存在一条从u到v的路径. Tarjan ...

  9. wc&period;exe指令(C&plus;&plus;)

    https://github.com/kielingpao/wc 项目相关要求 wc.exe 是一个常见的工具,它能统计文本文件的字符数.单词数和行数.这个项目要求写一个命令行程序,模仿已有wc.ex ...

  10. POJ 2318--TOYS&lpar;二分找点,叉积判断方向&rpar;

    TOYS Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 17974   Accepted: 8539 Description ...