hdu 1242 Rescue
题目链接: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的更多相关文章
- hdu - 1242 Rescue && hdu - 2425 Hiking Trip (优先队列+bfs)
http://acm.hdu.edu.cn/showproblem.php?pid=1242 感觉题目没有表述清楚,angel的朋友应该不一定只有一个,那么正解就是a去搜索r,再用普通的bfs就能过了 ...
- hdu 1242 Rescue(bfs)
此刻再看优先队列,不像刚接触时的那般迷茫!这也许就是集训的成果吧! 加油!!!优先队列必须要搞定的! 这道题意很简单!自己定义优先级别! +++++++++++++++++++++++++++++++ ...
- 杭电 HDU 1242 Rescue
http://acm.hdu.edu.cn/showproblem.php?pid=1242 问题:牢房里有墙(#),警卫(x)和道路( . ),天使被关在牢房里位置为a,你的位置在r处,杀死一个警卫 ...
- HDU 1242 Rescue(优先队列)
题目来源: http://acm.hdu.edu.cn/showproblem.php?pid=1242 题目描述: Problem Description Angel was caught by ...
- HDU 1242 Rescue(BFS+优先队列)
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1242 题目描述: Problem Description Angel was caught by t ...
- HDU 1242 -Rescue (双向BFS)&&( BFS+优先队列)
题目链接:Rescue 进度落下的太多了,哎╮(╯▽╰)╭,渣渣我总是埋怨进度比别人慢...为什么不试着改变一下捏.... 開始以为是水题,想敲一下练手的,后来发现并非一个简单的搜索题,BFS做肯定出 ...
- hdu 1242:Rescue(BFS广搜 + 优先队列)
Rescue Time Limit : 2000/1000ms (Java/Other) Memory Limit : 65536/32768K (Java/Other) Total Submis ...
- HDU 1242 Rescue (BFS(广度优先搜索))
Rescue Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submis ...
- HDU 1242 Rescue(BFS),ZOJ 1649
题目链接 ZOJ链接 Problem Description Angel was caught by the MOLIGPY! He was put in prison by Moligpy. The ...
随机推荐
- ACM题目————马拦过河卒
题目描述 棋盘上A点有一个过河卒,需要走到目标B点.卒行走的规则:可以向下.或者向右.同时在棋盘上C点有一个对方的马,该马所在的点和所有跳跃一步可达的点称为对方马的控制点.因此称之为“马拦过河卒”. ...
- 移动端web出现的一系列问题
今天做移动端的web,在做后期处理的时候,发现了非常多的问题.下面我分别列举一下吧~~ 1.移动端浏览器众多,各种浏览器之间的显示等都有差异,很多需要单独处理,于是我需要判断分别是什么浏览器.js代码 ...
- 这题实在不知道起啥名好了 分类: sdutOJ 2015-06-22 17:17 19人阅读 评论(0) 收藏
这题实在不知道起啥名好了 Time Limit: 1000ms Memory limit: 65536K 有疑问?点这里^_^ 题目描述 懒得想背景故事了,开门见山. 有一个长度为n的整数数列A ...
- CentOS 5/6.X 使用 EPEL YUM源
参考:http://www.linuxidc.com/Linux/2013-08/88523.htm 大纲 一.什么是EPEL? 二.与163 YUM源比较 三.CentOS 5.X 安装使用EPEL ...
- WP8.1简单项目 《在线词典》
为什么要做这个词典? 学了正则表达式要运用 增加WP开发熟练度 项目中运用了那些技术? HttpClient 正则表达式 数据绑定 详解 通过http://cn.bing.com/dict/searc ...
- Mybatis like 模糊查询问题
1.mysql:LIKE CONCAT('%',#{empname},'%' ) 或者 LIKE CONCAT('%',‘${empname}’,'%' ) 2.oracle:LIKE '%'||#{ ...
- BZOJ 2666: [cqoi2012]组装
题目链接:http://www.lydsy.com:808/JudgeOnline/problem.php?id=2666 题意:n种零件,m个位置,每个位置有一种零件.求一个位置x,使得cost(1 ...
- Cheatsheet: 2015 01.01~ 01.31
JAVA JVM Architecture Improving Lock Performance in Java 10 Best Java Tools That Every Java Programm ...
- Topic Model
Topic Model 标签(空格分隔): 机器学习 \(\Gamma\)函数 \(\Gamma\)函数可以看做是阶乘在实数域上的推广,即: \(\Gamma(x) = \int_{0}^{+\inf ...
- Dede CMS 5.5 升级到 5.7 SP1
Dede CMS 5.5 的漏洞实在是太多了,三天两头被Hacker们挂马.话说挂这些破网址真的能带来丰厚的回报吗?做人要厚道啊. 闲话少说,我按照网上的升级到5.5升级到5.7不出错的方法,升级 ...