HDOJ 1180: 诡异的楼梯
来源:互联网 发布:docker 端口 映射 编辑:程序博客网 时间:2024/06/10 03:05
其实这是一道水题,因为有人问所以做了一下。
第一次知道HDOJ AC数1000+的题目我也可以写将近一个小时。。
一道诡异的水题搞得我整个中午都诡异了。。。
俗话说的好,做水题伤身。
俗话又说的好,做水题还犯脑残错误更伤身。
俗话还说的好,脑残无药医啊啊啊啊啊啊啊啊
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1180
题目大意:
给定一个n*m的地图,给定了起点S和终点T。
某些格子上有障碍,有些格子上有楼梯。
有障碍的格子不能走,有楼梯的格子只有楼梯的方向跟行进方向相同时才能走。
楼梯每分钟变换一次方向(横向或竖向)。
每走一步花费1分钟,走楼梯的话可以直接走到楼梯对面,也是花费一分钟。
没有两个相邻的楼梯,人不能在楼梯上停留。
求需花费的最小时间。
算法:
简单的BFS。
显然距离要保留两个量,分别对应时间是奇数和时间是偶数时。
因为每次搜索到下一层的节点时,不管是走平地、走楼梯还是站着不动,时间都必定会加1,所以队列中的节点符合时间上的单调性。
还要注意一下在原地不动的情况。只有在S、T以及空地处才可以停留。
代码如下:
身心健康BFS版:
#include<cstdio>#include<algorithm>#include<queue>#include<cstring>#define st first#define nd second#define mp make_pairusing namespace std;typedef pair<int,int> PII;const int MAXN=50;char s[MAXN][MAXN];int mm[MAXN][MAXN];int d[MAXN][MAXN][2];int dx[5]= {1,-1,0,0,0};int dy[5]= {0,0,1,-1,0};queue<PII>q;int n,m;int get_id(int x, int y) { return (x-1)*m+y-1;}int main() { while(scanf("%d%d",&n,&m)==2) { memset(d,-1,sizeof(d)); memset(mm,-1,sizeof(mm)); for(int i=0; i<n; i++) { scanf("%s",s[i]); } int S,T; for(int i=0; i<n; i++) { for(int j=0; j<m; j++) { if(s[i][j]=='|') { mm[i+1][j+1]=0; } else if(s[i][j]=='-') { mm[i+1][j+1]=1; } else if(s[i][j]=='.') { mm[i+1][j+1]=2; } else if(s[i][j]=='S') { S=get_id(i+1,j+1); mm[i+1][j+1]=2; } else if(s[i][j]=='T') { T=get_id(i+1,j+1); mm[i+1][j+1]=2; } } } while(!q.empty()) { q.pop(); } q.push(mp(S,0)); d[S/m+1][S%m+1][0]=0; while(!q.empty()) { int x=q.front().st; if(x==T) { break; } int y=x%m+1; x=x/m+1; int state=q.front().nd; q.pop(); for(int i=0; i<5; i++) { int nx=x+dx[i]; int ny=y+dy[i]; if(mm[nx][ny]==-1) { continue; } if((mm[nx][ny]<2)&&((mm[nx][ny]^state)==(i>>1))) { nx+=dx[i]; ny+=dy[i]; } else if((mm[nx][ny]<2)&&((mm[nx][ny]^state)!=(i>>1))) { continue; } if(mm[nx][ny]==-1) { continue; } if(d[nx][ny][state^1]==-1||d[nx][ny][state^1]>d[x][y][state]+1) { d[nx][ny][state^1]=d[x][y][state]+1; q.push(mp(get_id(nx,ny),state^1)); } } } if(d[T/m+1][T%m+1][0]!=-1&&d[T/m+1][T%m+1][1]!=-1) { printf("%d\n",min(d[T/m+1][T%m+1][0],d[T/m+1][T%m+1][1])); } else { printf("%d\n",max(d[T/m+1][T%m+1][0],d[T/m+1][T%m+1][1])); } } return 0;}
闲的蛋疼A*版:
其实为什么叫它闲的蛋疼A*版呢,因为这道题本来就跑了0ms,我就是再优化也看不出效果来。
那么既然如此为什么还要写A*了呢,因为我闲的蛋疼啊。。
至于我为什么闲的蛋疼呢?
让你连着上一个礼拜数院的专业课,你试试。。
不仅讲得很难,而且讲得很快,所幸完全听不懂,好在是上全天。
呵呵呵呵。。。俗话说得好。。。
you say he can't, you can you up.
#include<cstdio>#include<algorithm>#include<queue>#include<vector>#include<cstring>#define st first#define nd second#define mp make_pairusing namespace std;typedef pair<int,int> PII;const int MAXN=50;char s[MAXN][MAXN];int mm[MAXN][MAXN];int d[MAXN][MAXN][2],h[MAXN*MAXN];bool vis[MAXN][MAXN][2];int dx[5]= {1,-1,0,0,0};int dy[5]= {0,0,1,-1,0};int n,m;struct cmp { bool operator()(const pair<PII,int>& a, const pair<PII,int>& b) { return a.st.nd+h[a.st.st]>b.st.nd+h[b.st.st]; }};priority_queue <pair<PII,int> , vector<pair<PII,int> >, cmp> q;int get_id(int x, int y) { return (x-1)*m+y-1;}void bfs(int S) { memset(h,-1,sizeof(h)); h[S]=0; queue<int>q; q.push(S); while(!q.empty()) { int x=q.front(); int y=x%m+1; x=x/m+1; q.pop(); for(int i=0; i<4; i++) { int nx=x+dx[i]; int ny=y+dy[i]; if(mm[nx][ny]==-1) { continue; } if(h[get_id(nx,ny)]==-1) { h[get_id(nx,ny)]=h[get_id(x,y)]+1; q.push(get_id(nx,ny)); } } }}int main() { while(scanf("%d%d",&n,&m)==2) { memset(d,-1,sizeof(d)); memset(mm,-1,sizeof(mm)); memset(vis,0,sizeof(vis)); for(int i=0; i<n; i++) { scanf("%s",s[i]); } int S,T; for(int i=0; i<n; i++) { for(int j=0; j<m; j++) { if(s[i][j]=='|') { mm[i+1][j+1]=0; } else if(s[i][j]=='-') { mm[i+1][j+1]=1; } else if(s[i][j]=='.') { mm[i+1][j+1]=2; } else if(s[i][j]=='S') { S=get_id(i+1,j+1); mm[i+1][j+1]=2; } else if(s[i][j]=='T') { T=get_id(i+1,j+1); mm[i+1][j+1]=2; } } } bfs(S); while(!q.empty()) { q.pop(); } q.push(mp(mp(S,0),0)); d[S/m+1][S%m+1][0]=0; while(!q.empty()) { int x=q.top().st.st; if(x==T) { break; } int y=x%m+1; x=x/m+1; int state=q.top().nd; q.pop(); if(vis[x][y][state]) { continue; } vis[x][y][state]=true; for(int i=0; i<5; i++) { int nx=x+dx[i]; int ny=y+dy[i]; if(mm[nx][ny]==-1) { continue; } if((mm[nx][ny]<2)&&((mm[nx][ny]^state)==(i>>1))) { nx+=dx[i]; ny+=dy[i]; } else if((mm[nx][ny]<2)&&((mm[nx][ny]^state)!=(i>>1))) { continue; } if(mm[nx][ny]==-1) { continue; } if(d[nx][ny][state^1]==-1||d[nx][ny][state^1]>d[x][y][state]+1) { d[nx][ny][state^1]=d[x][y][state]+1; q.push(mp(mp(get_id(nx,ny),d[nx][ny][state^1]),state^1)); } } } if(d[T/m+1][T%m+1][0]!=-1&&d[T/m+1][T%m+1][1]!=-1) { printf("%d\n",min(d[T/m+1][T%m+1][0],d[T/m+1][T%m+1][1])); } else { printf("%d\n",max(d[T/m+1][T%m+1][0],d[T/m+1][T%m+1][1])); } } return 0;}
PS:求有时间的大神帮我试一下迭代加深dfs跑的怎么样啊。。。实在是没那个心力了。。。orz
- HDOJ 1180: 诡异的楼梯
- HDOJ 1180 诡异的楼梯
- hdoj-【1180 诡异的楼梯】
- HDOJ 1180 诡异的楼梯 DFS
- hdoj 1180 诡异的楼梯(BFS)
- HDOJ 1180 诡异的楼梯 (BFS)
- hdoj 诡异的楼梯 1180 (bfs&&奇偶判断) 好题
- HDOJ/HDU 1180 诡异的楼梯(经典BFS-详解)
- hdoj 1180 诡异的楼梯 bfs bfs bfs
- hdu 1180 诡异的楼梯
- hdu 1180 诡异的楼梯
- HDU 1180 诡异的楼梯
- Hdu-1180(诡异的楼梯)
- HDU 1180 诡异的楼梯
- hdu 1180 诡异的楼梯
- 诡异的楼梯 hdu 1180
- HDU-1180 诡异的楼梯
- hdu 1180 诡异的楼梯
- delete与truncate区别
- GDB多进程调试
- 求平均值的时候,分母到底该如何选择?
- Oracle(二)- count的用法
- 写在最早
- HDOJ 1180: 诡异的楼梯
- 论分类(三)-感知器篇
- 两个大数(位数在50位以上)相加
- Oracle(二)-多表链接查询
- Github入门1之设置git
- 虚拟机Ubuntu 13.04 在Easy Install 下安装vmware tools 过程及遇到的问题总结
- 设计模式(三)-- 适配器模式(Adapter)
- QQ美女找茬辅助器源代码~~~
- IE浏览器的“浏览器模式”和“文档模式”