hdu 1180 诡异的楼梯【BFS+优先队列】
来源:互联网 发布:用c语言求最小公倍数 编辑:程序博客网 时间:2024/06/05 23:55
诡异的楼梯
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/65536 K (Java/Others)Total Submission(s): 11695 Accepted Submission(s): 2897
Problem Description
Hogwarts正式开学以后,Harry发现在Hogwarts里,某些楼梯并不是静止不动的,相反,他们每隔一分钟就变动一次方向.
比如下面的例子里,一开始楼梯在竖直方向,一分钟以后它移动到了水平方向,再过一分钟它又回到了竖直方向.Harry发现对他来说很难找到能使得他最快到达目的地的路线,这时Ron(Harry最好的朋友)告诉Harry正好有一个魔法道具可以帮助他寻找这样的路线,而那个魔法道具上的咒语,正是由你纂写的.
比如下面的例子里,一开始楼梯在竖直方向,一分钟以后它移动到了水平方向,再过一分钟它又回到了竖直方向.Harry发现对他来说很难找到能使得他最快到达目的地的路线,这时Ron(Harry最好的朋友)告诉Harry正好有一个魔法道具可以帮助他寻找这样的路线,而那个魔法道具上的咒语,正是由你纂写的.
Input
测试数据有多组,每组的表述如下:
第一行有两个数,M和N,接下来是一个M行N列的地图,'*'表示障碍物,'.'表示走廊,'|'或者'-'表示一个楼梯,并且标明了它在一开始时所处的位置:'|'表示的楼梯在最开始是竖直方向,'-'表示的楼梯在一开始是水平方向.地图中还有一个'S'是起点,'T'是目标,0<=M,N<=20,地图中不会出现两个相连的梯子.Harry每秒只能停留在'.'或'S'和'T'所标记的格子内.
第一行有两个数,M和N,接下来是一个M行N列的地图,'*'表示障碍物,'.'表示走廊,'|'或者'-'表示一个楼梯,并且标明了它在一开始时所处的位置:'|'表示的楼梯在最开始是竖直方向,'-'表示的楼梯在一开始是水平方向.地图中还有一个'S'是起点,'T'是目标,0<=M,N<=20,地图中不会出现两个相连的梯子.Harry每秒只能停留在'.'或'S'和'T'所标记的格子内.
Output
只有一行,包含一个数T,表示到达目标的最短时间.
注意:Harry只能每次走到相邻的格子而不能斜走,每移动一次恰好为一分钟,并且Harry登上楼梯并经过楼梯到达对面的整个过程只需要一分钟,Harry从来不在楼梯上停留.并且每次楼梯都恰好在Harry移动完毕以后才改变方向.
注意:Harry只能每次走到相邻的格子而不能斜走,每移动一次恰好为一分钟,并且Harry登上楼梯并经过楼梯到达对面的整个过程只需要一分钟,Harry从来不在楼梯上停留.并且每次楼梯都恰好在Harry移动完毕以后才改变方向.
Sample Input
5 5**..T**.*...|...*.*.S....
Sample Output
7地图如下:HintHint
这个题难想的地方是原地不动的情况。如果这个情况考虑到了,其实问题也就解决了。
之所以用到了优先队列,其原因就是有原地不动的情况,所以我们这里控制时间最优,使用优先队列。
思路:
从起点出发,控制楼梯方向和走向,然后根据当前走的时间判断楼梯方向,然后走向的方向如果能够顺着楼梯走下去,那就走两次。
这里口述可能并不是很清楚,这里对应代码:
void bfs(int x,int y){ memset(vis,0,sizeof(vis)); vis[x][y]=1; now.x=x; now.y=y; now.output=0; priority_queue<zuobiao>s; s.push(now); while(!s.empty()) { now=s.top(); //printf("%d %d %d\n",now.x,now.y,now.output); if(a[now.x][now.y]=='T') { printf("%d\n",now.output); return ; } s.pop(); for(int i=0;i<5;i++)//0-右、1-左、2、下、3、上。 { if(i==4) { nex.x=now.x; nex.y=now.y; nex.output=now.output+1; s.push(nex); continue; } nex.x=now.x+fx[i]; nex.y=now.y+fy[i]; if(nex.x>=0&&nex.x<n&&nex.y>=0&&nex.y<m&&a[nex.x][nex.y]!='*'&&vis[nex.x][nex.y]==0)//必须在能走的条件下,才能走向下一步 { if(a[nex.x][nex.y]=='.'||a[nex.x][nex.y]=='T') { nex.output=now.output+1; vis[nex.x][nex.y]=1; s.push(nex); } if(a[nex.x][nex.y]=='|')//0-右、1-左、2、下、3、上。 { //printf("%d\n",now.output); if(now.output%2==0&&i==2||i==3&&now.output%2==0)//如果当前走的时间是偶数,相当于梯子没有动 { //printf("yes\n"); nex.x=now.x+2*fx[i];//对应走的方向走两次(题干要求) nex.y=now.y+2*fy[i]; if(nex.x>=0&&nex.x<n&&nex.y>=0&&nex.y<m&&a[nex.x][nex.y]!='*'&&vis[nex.x][nex.y]==0)//并且走到的地方也是可行的地方 { //printf("%d %d\n",nex.x,nex.y); nex.output=now.output+1; vis[nex.x][nex.y]=1; s.push(nex); } } if(now.output%2==1&&i==0||i==1&&now.output%2==1) { // printf("yes2\n"); //printf("%d %d\n",now.output,i); nex.x=now.x+2*fx[i]; nex.y=now.y+2*fy[i]; if(nex.x>=0&&nex.x<n&&nex.y>=0&&nex.y<m&&a[nex.x][nex.y]!='*'&&vis[nex.x][nex.y]==0) { nex.output=now.output+1; vis[nex.x][nex.y]=1; s.push(nex); } } } if(a[nex.x][nex.y]=='-')//0-右、1-左、2、下、3、上。 { if(now.output%2==0&&i==0||i==1&&now.output%2==0) { nex.x=now.x+2*fx[i]; nex.y=now.y+2*fy[i]; if(nex.x>=0&&nex.x<n&&nex.y>=0&&nex.y<m&&a[nex.x][nex.y]!='*'&&vis[nex.x][nex.y]==0) { nex.output=now.output+1; vis[nex.x][nex.y]=1; s.push(nex); } } if(now.output%2==1&&i==2||i==3&&now.output%2==1) { nex.x=now.x+2*fx[i]; nex.y=now.y+2*fy[i]; if(nex.x>=0&&nex.x<n&&nex.y>=0&&nex.y<m&&a[nex.x][nex.y]!='*'&&vis[nex.x][nex.y]==0) { nex.output=now.output+1; vis[nex.x][nex.y]=1; s.push(nex); } } } } } } return ;}把这么些个情况都考虑到之后,整个思路缜密一些,题目就能够AC了:
#include<stdio.h>#include<string.h>#include<queue>using namespace std;struct zuobiao{ int x,y,output; friend bool operator <(zuobiao a,zuobiao b) { return a.output>b.output; }}now,nex;int n,m;int vis[50][50];char a[50][50];int fx[4]={0,0,1,-1};//0-右、1-左、2、下、3、上。int fy[4]={1,-1,0,0};void bfs(int x,int y){ memset(vis,0,sizeof(vis)); vis[x][y]=1; now.x=x; now.y=y; now.output=0; priority_queue<zuobiao>s; s.push(now); while(!s.empty()) { now=s.top(); //printf("%d %d %d\n",now.x,now.y,now.output); if(a[now.x][now.y]=='T') { printf("%d\n",now.output); return ; } s.pop(); for(int i=0;i<5;i++)//0-右、1-左、2、下、3、上。 { if(i==4) { nex.x=now.x; nex.y=now.y; nex.output=now.output+1; s.push(nex); continue; } nex.x=now.x+fx[i]; nex.y=now.y+fy[i]; if(nex.x>=0&&nex.x<n&&nex.y>=0&&nex.y<m&&a[nex.x][nex.y]!='*'&&vis[nex.x][nex.y]==0) { if(a[nex.x][nex.y]=='.'||a[nex.x][nex.y]=='T') { nex.output=now.output+1; vis[nex.x][nex.y]=1; s.push(nex); } if(a[nex.x][nex.y]=='|')//0-右、1-左、2、下、3、上。 { //printf("%d\n",now.output); if(now.output%2==0&&i==2||i==3&&now.output%2==0) { //printf("yes\n"); nex.x=now.x+2*fx[i]; nex.y=now.y+2*fy[i]; if(nex.x>=0&&nex.x<n&&nex.y>=0&&nex.y<m&&a[nex.x][nex.y]!='*'&&vis[nex.x][nex.y]==0) { //printf("%d %d\n",nex.x,nex.y); nex.output=now.output+1; vis[nex.x][nex.y]=1; s.push(nex); } } if(now.output%2==1&&i==0||i==1&&now.output%2==1) { // printf("yes2\n"); //printf("%d %d\n",now.output,i); nex.x=now.x+2*fx[i]; nex.y=now.y+2*fy[i]; if(nex.x>=0&&nex.x<n&&nex.y>=0&&nex.y<m&&a[nex.x][nex.y]!='*'&&vis[nex.x][nex.y]==0) { nex.output=now.output+1; vis[nex.x][nex.y]=1; s.push(nex); } } } if(a[nex.x][nex.y]=='-')//0-右、1-左、2、下、3、上。 { if(now.output%2==0&&i==0||i==1&&now.output%2==0) { nex.x=now.x+2*fx[i]; nex.y=now.y+2*fy[i]; if(nex.x>=0&&nex.x<n&&nex.y>=0&&nex.y<m&&a[nex.x][nex.y]!='*'&&vis[nex.x][nex.y]==0) { nex.output=now.output+1; vis[nex.x][nex.y]=1; s.push(nex); } } if(now.output%2==1&&i==2||i==3&&now.output%2==1) { nex.x=now.x+2*fx[i]; nex.y=now.y+2*fy[i]; if(nex.x>=0&&nex.x<n&&nex.y>=0&&nex.y<m&&a[nex.x][nex.y]!='*'&&vis[nex.x][nex.y]==0) { nex.output=now.output+1; vis[nex.x][nex.y]=1; s.push(nex); } } } } } } return ;}int main(){ while(~scanf("%d%d",&n,&m)) { int qidianx,qidiany; for(int i=0;i<n;i++) { scanf("%s",a[i]); for(int j=0;j<m;j++) { if(a[i][j]=='S') { qidianx=i; qidiany=j; } } } bfs(qidianx,qidiany); }}
0 0
- hdu 1180 诡异的楼梯(bfs+优先队列)
- 【BFS&&优先队列】HDU 1180 诡异的楼梯
- HDU 1180 诡异的楼梯(bfs+优先队列)
- hdu 1180 诡异的楼梯【BFS+优先队列】
- hdu 1180 诡异的楼梯 bfs+优先队列 解题报告
- HDU 1180 诡异的楼梯【BFS广搜+优先队列】
- HDU 1180 诡异的楼梯(BFS+优先队列)
- HDU 1180 诡异的楼梯 -- 优先队列
- hdu1180诡异的楼梯(BFS+优先队列)
- hdu1180-诡异的楼梯(bfs+优先队列)
- 【搜索之BFS + 优先队列】杭电 hdu 1180 诡异的楼梯
- HDU 1180 诡异的楼梯(BFS,用优先队列过)
- HDU 1180 诡异的楼梯(广搜、优先队列)
- hdu 1180 诡异的楼梯(优先队列)
- HDU1180——诡异的楼梯(BFS+优先队列)
- hdu1180 诡异的楼梯(BFS+优先队列)
- hdu1180 诡异的楼梯(优先队列bfs)
- HDU1180 诡异的楼梯(广搜BFS+优先队列)
- jquery 下载地址
- http server原理,nginx与php之间是如何工作的
- “鸽姆微媒体+互联网商业智慧创业孵化器”会议培训项目方案
- SQLiteOpenHelper对数据库进行版本管理
- 设计模式系列:单例模式
- hdu 1180 诡异的楼梯【BFS+优先队列】
- UNIMODAL PALINDROMIC DECOMPOSITIONS-----动态规划-------单峰回文序列分解
- 设计模式系列:工厂方法模式
- iOS:UITextView、UITextField检测用户是否完成输入的选择
- 动态规划入门
- RANGE MINIUM/MAXIUM QUERY问题
- python 在windows下如何切换工作路径
- 设计模式系列:抽象工厂模式
- 排序算法之冒泡排序