HDU 1180 (诡异的楼梯)+HDU 2102 (A计划)
2015-08-03 15:37
176 查看
之前自己也写过这两题,但是感觉真是神坑,不管怎么都过不了。今天巍神开了专题后又有这两题,于是我就开始认真写和debug。竟然AC了好开心。来总结下坑点。
诡异的楼梯
题意: S是起点,T是终点,*是障碍物,| 和 — 是楼梯。楼梯很特别,每隔一秒换一个方向。人可以停留在任意一个点上,但是不能停留在楼梯上。
解题方法: 利用BFS优先队列。有一点需要注意的是当你走到楼梯口时,从楼梯这边到楼梯那边只需要一秒的时间,且如果楼梯方向与你的行走方向不一致的时候,你可以在原地等一秒钟让楼梯换了方向再过去。还有就是可能楼梯对面就是终点,也可能是障碍物。
HDU上的数据很水,我感觉我是水过的。
A计划
题意: 两层的地图,S是起点,P是终点。#是时空传输机,*是障碍物。
解题思路: 同样是BFS优先队列。
起点和终点有可能在同一层
遇到传输机的时候必须传输,没有第二种选择
当传输过去是墙,直接撞死
当传输机的对面也是传输机的时候,然会就会在两层之间反复传输,得不出结果
诡异的楼梯
题意: S是起点,T是终点,*是障碍物,| 和 — 是楼梯。楼梯很特别,每隔一秒换一个方向。人可以停留在任意一个点上,但是不能停留在楼梯上。
解题方法: 利用BFS优先队列。有一点需要注意的是当你走到楼梯口时,从楼梯这边到楼梯那边只需要一秒的时间,且如果楼梯方向与你的行走方向不一致的时候,你可以在原地等一秒钟让楼梯换了方向再过去。还有就是可能楼梯对面就是终点,也可能是障碍物。
HDU上的数据很水,我感觉我是水过的。
[code]#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <queue> using namespace std; const int N = 20+5; struct Node { int x,y,cnt; friend bool operator <(const Node a ,const Node b) { return a.cnt > b.cnt; } }; int dir[4][2]={0,1,1,0,0,-1,-1,0}; bool vis ; char Map ; int n,m; bool check(int x,int y) { if(x<1||x>n) return false; if(y<1||y>m) return false; if(!vis[x][y]) return false; if(Map[x][y]=='*') return false; else return true; } bool judge(int x,int y,int i,int cnt)//判断这个楼梯是否可以现在通过 { if(cnt%2) { if(Map[x][y]=='|') { if(i==0||i==2) return true; else return false; } if(Map[x][y]=='-') { if(i==1||i==3) return true; else return false; } } else { if(Map[x][y]=='-') { if(i==0||i==2) return true; else return false; } if(Map[x][y]=='|') { if(i==1||i==3) return true; else return false; } } } int bfs(int x,int y) { Node now,next; priority_queue<Node> que; now.x=x; now.y=y; now.cnt=0; vis[now.x][now.y]=false; que.push(now); while(!que.empty()) { now=que.top(); que.pop(); if(Map[now.x][now.y]=='T') return now.cnt; for(int i=0;i<4;i++) { next.x=now.x+dir[i][0]; next.y=now.y+dir[i][1]; if(!check(next.x,next.y)) continue; if(Map[next.x][next.y]!='|'&&Map[next.x][next.y]!='-')//两种情况分开讨论 { next.cnt=now.cnt+1; vis[next.x][next.y]=false; que.push(next); } else { if(!judge(next.x,next.y,i,now.cnt)) next.cnt=now.cnt+2; else next.cnt=now.cnt+1; next.x+=dir[i][0]; next.y+=dir[i][1]; if(!check(next.x,next.y)) continue; vis[next.x][next.y]=false; que.push(next); } } } return -1; } int main() { while(~scanf("%d%d",&n,&m)) { int x,y; for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) { scanf(" %c",&Map[i][j]); if(Map[i][j]=='S') x=i,y=j; } memset(vis,true,sizeof(vis)); printf("%d\n",bfs(x,y)); } return 0; }
A计划
题意: 两层的地图,S是起点,P是终点。#是时空传输机,*是障碍物。
解题思路: 同样是BFS优先队列。
起点和终点有可能在同一层
遇到传输机的时候必须传输,没有第二种选择
当传输过去是墙,直接撞死
当传输机的对面也是传输机的时候,然会就会在两层之间反复传输,得不出结果
[code]#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <queue> using namespace std; int dir[4][2]={0,1,1,0,0,-1,-1,0}; struct Node { int x,y,z,cnt; friend bool operator < (const Node a,const Node b) { return a.cnt > b.cnt; } }; int n,m,T; const int N = 12; char Map[2] ; bool vis[2] ; bool bfs(int x,int y ,int z) { Node now,next; priority_queue<Node> que; now.z=z; now.x=x; now.y=y; now.cnt=0; vis[z][x][y]=false; que.push(now); while(!que.empty()) { now=que.top(); que.pop(); if(Map[now.z][now.x][now.y]=='P'&&now.cnt<=T) return true; if(now.cnt>T) return false; for(int i=0;i<4;i++) { next.z=now.z; next.x=now.x+dir[i][0]; next.y=now.y+dir[i][1]; if(next.x<1||next.x>n) continue; if(next.y<1||next.y>m) continue; if(!vis[next.z][next.x][next.y]) continue; if(Map[next.z][next.x][next.y]=='#') { vis[next.z][next.x][next.y]=false; if(next.z) next.z=0; else next.z=1; if(Map[next.z][next.x][next.y]=='#') continue;//传输过去也是传输机的时候 } if(Map[next.z][next.x][next.y]=='*') continue;//传输过去是墙的时候 if(!vis[next.z][next.x][next.y]) continue; vis[next.z][next.x][next.y]=false; next.cnt=now.cnt+1; que.push(next); } } return false; } int main() { int t; scanf("%d",&t); while(t--) { scanf("%d %d %d",&n,&m,&T); int x,y,z; for(int k=0;k<2;k++) for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) { scanf(" %c",&Map[k][i][j]); if(Map[k][i][j]=='S') x=i,y=j,z=k; } memset(vis,true,sizeof(vis)); puts(bfs(x,y,z)?"YES":"NO"); } return 0; }
相关文章推荐
- 取消IE默认下载工具为迅雷
- MSDN(电驴)
- Visaul Studio 常用快捷键的动画演示
- php-fpm内存占满的问题
- mysql之事务和锁
- 集合的内存管理
- struts拦截器
- OProfile -- 重点是配置文件
- JavaScript Array(数组)对象
- COJ970 WZJ的数据结构(负三十)
- 双系统下恢复Ubuntu引导菜单
- Algorithms—165.Compare Version Numbers
- AFNetWorking 简单使用
- android 检测sqlite数据表中字段(列)是否存在
- Yii 控制器验证ajax提交的数据的两种方式
- c#中decimal的去0显示
- unix环境高级编程-教材代码编译过程
- POJ - 2195 Going Home (MCMF)
- Java中Array与ArrayList的主要区别
- 成员变量和局部变量