hdu 1180:诡异的楼梯(BFS广搜)
诡异的楼梯
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/65536 K (Java/Others)
Total Submission(s): 7642 Accepted Submission(s): 1830
比如下面的例子里,一开始楼梯在竖直方向,一分钟以后它移动到了水平方向,再过一分钟它又回到了竖直方向.Harry发现对他来说很难找到能使得他最快到达目的地的路线,这时Ron(Harry最好的朋友)告诉Harry正好有一个魔法道具可以帮助他寻找这样的路线,而那个魔法道具上的咒语,正是由你纂写的.
第一行有两个数,M和N,接下来是一个M行N列的地图,'*'表示障碍物,'.'表示走廊,'|'或者'-'表示一个楼梯,并且标明了它在一开始时所处的位置:'|'表示的楼梯在最开始是竖直方向,'-'表示的楼梯在一开始是水平方向.地图中还有一个'S'是起点,'T'是目标,0<=M,N<=20,地图中不会出现两个相连的梯子.Harry每秒只能停留在'.'或'S'和'T'所标记的格子内.
注意:Harry只能每次走到相邻的格子而不能斜走,每移动一次恰好为一分钟,并且Harry登上楼梯并经过楼梯到达对面的整个过程只需要一分钟,Harry从来不在楼梯上停留.并且每次楼梯都恰好在Harry移动完毕以后才改变方向.
**..T
**.*.
..|..
.*.*.
S....
Hint
地图如下: 
if | //遇到的楼梯初始是‘|’
if step是奇数,变化
if i 是奇数
不能通过
else
能通过
else //不变
if i 是奇数
能通过
else
不能通过
if - //遇到的楼梯初始是‘-’
if step是奇数,变化
if i 是奇数
能通过
else
不能通过
else //不变
if i 是奇数
不能通过
else
能通过
另外注意两点:
1.剪枝。有一个可以剪枝的地方:遇到楼梯先判断楼梯对面是否走过,如果已经走过,直接退出本次循环。
2.超时问题。一定要处理好step(遇到楼梯时的步数),因为step是会变的,所以这次如果不能通过,下次也一定能通过。像我一开始把“step”整成了不会变的,测试结果对了,提交却一直超时。
#include <iostream>
#include <queue>
#include <string.h>
using namespace std;
char a[][];
bool isw[][];
int dx[] = {,,,-};
int dy[] = {,,-,};
int M,N;
int startx,starty;
bool pass; //能否通过梯子
struct NODE{
int x;
int y;
int step;
};
int abs(int n)
{
return n>?n:-n;
}
bool judge(int x,int y,int i,int step)
{
if( x< || y< || x>M ||y>N ) //越界
return ;
if( isw[x][y] ) //走过了
return ;
if( a[x][y]=='*' ) //遇到墙
return ;
if( a[x][y]=='|' ){
if( isw[x+dx[i]][y+dy[i]] )
return ;
if( step% ){ //奇,变
if( i% ) //奇数
pass = false; //不可以通过
else
pass = true; //可以通过
}
else { //不变
if( i% ) //奇数
pass = true; //可以通过
else
pass = false; //不可以通过
}
}
else if( a[x][y]=='-' ){
if( isw[x+dx[i]][y+dy[i]] )
return ;
if( step% ){ //奇,变
if( i% ) //奇数
pass = true; //可以通过
else
pass = false; //不可以通过
}
else{ //不变
if( i% ) //奇数
pass = false; //不可以通过
else
pass = true; //可以通过
}
}
return ;
}
int bfs(int x,int y)
{
queue <NODE> q;
NODE cur,next;
cur.x = x;
cur.y = y;
cur.step = ;
q.push(cur); //第一个节点入队
while(!q.empty()){
//队首出队
cur = q.front();
q.pop();
if(a[cur.x][cur.y]=='T') //如果这一步已经走到了终点,则输出走到这一步的步数
return cur.step;
for(int i=;i<;i++){ //下一层节点入队
int nx = cur.x + dx[i];
int ny = cur.y + dy[i];
if( judge(nx,ny,i,cur.step) ) //判定这一步可走否
continue;
if(a[nx][ny]=='|' || a[nx][ny]=='-'){ //如果这一步是碰到梯子的
if(pass){ //可以通过梯子
nx += dx[i];
ny += dy[i];
}
else{ //不可以通过梯子
nx -= dx[i];
ny -= dy[i];
}
}
next.x = nx; //可走,记录下一步的位置
next.y = ny;
next.step = cur.step + ; //可走,步数累加
isw[next.x][next.y] = true; //可走,标记走过
q.push(next);
}
}
}
int main()
{
while(cin>>M>>N){
for(int i=;i<=M;i++)
for(int j=;j<=N;j++){
cin>>a[i][j];
if(a[i][j]=='S'){
startx = i;
starty = j;
}
}
memset(isw,,sizeof(isw));
isw[startx][starty] = true;
cout<<bfs(startx,starty)<<endl;
}
return ;
}
Freecode : www.cnblogs.com/yym2013
hdu 1180:诡异的楼梯(BFS广搜)的更多相关文章
- hdu 1180 诡异的楼梯(广搜,简单)
题目 挺简单的一道广搜题,只要用判断时间是偶数还是奇数就可以判断楼梯的方位,但是我这傻逼居然写了那么久啊那么久,我果然秀逗了,,,, #define _CRT_SECURE_NO_WARNINGS # ...
- HDU 1180 诡异的楼梯 (广搜)
题目链接 Problem Description Hogwarts正式开学以后,Harry发现在Hogwarts里,某些楼梯并不是静止不动的,相反,他们每隔一分钟就变动一次方向. 比如下面的例子里,一 ...
- hdu 1180 诡异的楼梯 (bfs)
诡异的楼梯 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/65536 K (Java/Others) Total Sub ...
- hdu 1180诡异的楼梯(bfs)
诡异的楼梯 Time Limit : 2000/1000ms (Java/Other) Memory Limit : 131072/65536K (Java/Other) Total Submis ...
- hdu - 1180 诡异的楼梯 (bfs+优先队列)
http://acm.hdu.edu.cn/showproblem.php?pid=1180 注意点就是楼梯是在harry移动完之后才会改变方向,那么只要统计到达这个点时间奇偶性,就可以知道当前楼梯是 ...
- HDU 1180 诡异的楼梯(超级经典的bfs之一,需多回顾)
传送门: http://acm.hdu.edu.cn/showproblem.php?pid=1180 诡异的楼梯 Time Limit: 2000/1000 MS (Java/Others) ...
- HDU 1180 诡异的楼梯(BFS)
诡异的楼梯 Time Limit:1000MS Memory Limit:65536KB 64bit IO Format:%I64d & %I64u Submit Status ...
- HDU 1180 诡异的楼梯【BFS/楼梯随时间变化】
诡异的楼梯 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/65536 K (Java/Others) Total Submis ...
- HDOJ/HDU 1180 诡异的楼梯(经典BFS-详解)
Problem Description Hogwarts正式开学以后,Harry发现在Hogwarts里,某些楼梯并不是静止不动的,相反,他们每隔一分钟就变动一次方向. 比如下面的例子里,一开始楼梯在 ...
随机推荐
- 基于skitter的轮播图炫酷效果,幻灯片的体验
概述 包含各种炫酷的轮播切换效果,插件小巧,与其他插件无冲突,可用于移动端和PC端 详细 代码下载:http://www.demodashi.com/demo/11939.html 你还在用原生的js ...
- linux下vi编辑文件
vi 文件名.进入读文件模式 按i进入编辑模式 按g切光标换到第一行,按G光标切换到最后一行. 按Esc退出编辑模式 :q退出 :wq保存退出 以上命名后面加上!表示强制运行
- 使用vs调试.net源代码
使用.NET Framework库参考源进行调试 您可能会想知道使用.NET Framework参考源的调试方式.在下面的示例中,您将看到一个我调用公用Console.WriteLine方法的工具.从 ...
- XML相关转换
1.将DataTable转换成xml字符串 //将DataTable转换成xml字符串: public string ConvertDataTableToXml(DataTable dt) { Mem ...
- layui更新表格单元格数据口,更新单元格的内容
//监听工具条 table.on('tool(edit)', function(obj){ var data = obj.data; if(obj.event === 'getinvitation') ...
- Go语言核心之美 4.3-多返回值
在Go语言中.函数能够有多个返回值,这个特性我们已经在之前的样例见过非常多,非常多标准库函数都会返回两个值,一个是期望得到的函数执行结果,另外一个是函数出错时的错误值. 以下的程序是findlinks ...
- 二级指针 (C语言)
二级指针又叫双指针.C语言中不存在引用,所以当你试图改变一个指针的值的时候必须使用二级指针.C++中可以使用引用类型来实现. 下面讲解C中的二级指针的使用方法. 例如我们使用指针来交换两个整型变量的值 ...
- 揭开Altera公司支持OpenCL的设计工具的神秘面纱
将程序中处理负荷较大的工作分配给加速器LSI的“异构计算(Heterogeneous Computing)”将踏出崭新的一步.美国Altera公司将于2013年内开始面向普通用户提供可自动由按照异构计 ...
- Linux系统CPU频率调整工具使用
现在的CPU耗电很大,按需调节CPU频率对普通桌面及移动设备节能有重要的意义,目前多数Linux发行版都已经默认启用了这个功能,但在一些像数据库,集群系统等特别需要CPU高性能的服务器环境中,Linu ...
- sim900GPRS模块ppp拨号上网
--------------------------------------------- 主机操作系统:Centos 6.5 交叉编译器环境:arm-linux-gcc-4.5.4 开发板平台: F ...