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里,某些楼梯并不是静止不动的,相反,他们每隔一分钟就变动一次方向. 比如下面的例子里,一开始楼梯在 ...
随机推荐
- How to add a button in the seletions "More"
<?xml version="1.0" encoding="utf-8"?> <openerp> <data> <re ...
- 关于SO_REUSEADDR的使用说明~
参考WINDOWS 网络编程技术 1. 可以对一个端口进行多次绑定,一般这个是不支持使用的: 2. 对于监听套接字,比较特殊.如果你定义了SO_REUSEADDR, ...
- oracle 存储过程 调用动态sql
oracle 存储过程 调用动态sql CreationTime--2018年8月16日11点25分 Author:Marydon 1.错误实现方式 --开始时间拼接' 00:00:00' V_S ...
- iOS 全屏侧滑/UIScrollView/UISlider间滑动冲突
代码地址如下:http://www.demodashi.com/demo/13848.html 效果预览 一.前期准备 有一个支持全屏侧滑返回的视图控制器ViewController,ViewCont ...
- js特效,轻松实现内容的无缝平滑滚动
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http ...
- 快速排序以及第k小元素的线性选择算法
简要介绍下快速排序的思想:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此 ...
- oracle 统计分析函数
http://www.cnblogs.com/advocate/archive/2010/11/16/1878693.html
- atitit.科技公司的超级武器--超级框架,到底要不要自己的框架??
atitit.科技公司的超级武器--超级框架,到底要不要自己的框架?? 我们生活的时代,,任何一个时代,总有人会以经济之类的理由劝阻人向未知领域探索,基本上,他们的理由无非几种: 1.把钱投到更需要的 ...
- commit
git blame -L 260, 270 a.xml no permissions fastbootsudo chown root:root fastbootsudo chmod +s fast ...
- oracle 使用occi方式 批量插入多条数据
if (vecInfo.empty()) { ; //数据为空,不上传,不上传标志设置为1,只有0表示上传成功 } std::string strUserName = userName; std::s ...