(hdu step 4.2.4)A strange lift(求从起点到终点的最小步数,限制条件是:在一维的情况下)
2015-02-17 17:44
543 查看
题目:
题目分析:
广搜题。在一维的情况下,求从起点到终点的最小步数。这道题有一下特点:
1)没有涉及障碍物的概念。也就是说每一点理论上都可以到达。在做搜索的题目的时候,一般都会有map[][]矩阵和vis[][]。前者用于存储整张地图的信息,如那些是路,那些事障碍物,公主(终点)在哪里,你(起点)在哪里。后者用于标记到达某一节点是的最小步数(个人习惯,这里的vis[][]是int类型的)。因为这道题中没有障碍物的概念,所以我们其实并不需要开一个map[][]数数组。
2)这道题是一维的。所以开vis数组的时候开到一维的就可以了。
3)每一点的步长不一样。之前我们接触的题目,大部分都是只能到达相邻节点,而这道题中,我们身处第一层的时候,有可能我们就只能直接到第三层,而不是到第二层。其实这也是由这道题中的“一维”的这个概念所限制的。你想想,如果在一位的情况下,每一节点只能到达相邻节点,那么在第一层就只能去到第二层。那么样例中所说的从第一层到第5层就之恩能够使一层一层的上了,就不是所谓的搜索题目了,因为在这种情况下按(5-1)次按钮就能到达指定楼层。
需要注意的是,从某一楼层出发以后,很可能不再回到该楼层,否则就死循环了。
代码如下:
/*
* d.cpp
*
* Created on: 2015年2月17日
* Author: Administrator
*/
#include <iostream>
#include <cstdio>
#include <queue>
using namespace std;
const int maxn = 205;
const int inf = 999999;
int vis[maxn];//用于标记访问有一个节点的最小步数
int dir[maxn];//某一个节点移到下一个节点的步长
int n;//节点的个数
int start;//起点
int end;//终点
struct Node{//节点
int floor;//用于标记现在位于第几层
int step;//到达现在这个位置所需要的步数
friend bool operator<(Node a,Node b){//用于实现在在优先队列中从小到大排序
return a.step > b.step;
}
};
/**
* 判断下一届点是否合法
*/
bool check(int floor){
if(floor < 0 || floor >= n){//判断当前楼层是否合法
return false;
}
return true;//表示当前楼层合法
}
int bfs(){
priority_queue<Node> q;
//初始化根节点
Node root;
root.floor = start;
root.step = 0;
Node k;
q.push(root);//根节点入队
while(!q.empty()){//如果队列非空
Node a = q.top();//每次去除対首元素
q.pop();
if(a.floor == end){//如果已经达到终点
return a.step;//返回到达终点所需要的步数
}
//第一个方向
k.floor = a.floor + dir[a.floor];//计算下一节点的位置
if(check(k.floor) == true){//如果下一节点的位置合法
k.step = a.step+1;//计算到达下一节点所需要的步数
if(vis[k.floor] > k.step){//如果之前到达目标节点所需要的步数>目前到达目标节点所需要的步数
vis[k.floor] = k.step;//更新到达当前节点所需要的最小步数
q.push(k);//将该元素入队
}
}
//第二个方向
k.floor = a.floor - dir[a.floor];
if(check(k.floor) == true){
k.step = a.step+1;
if(vis[k.floor] > k.step){
vis[k.floor] = k.step;
q.push(k);
}
}
}
return -1;//表示没有到达终点
}
int main(){
while(scanf("%d",&n)!=EOF,n){
scanf("%d%d",&start,&end);
start -= 1;//这里需要注意一下.位置我这里是从0来时算的
end -= 1;
int i;
for(i = 0 ; i < n ; ++i){
scanf("%d",&dir[i]);//初始化每一楼层的步长
}
memset(vis,inf,sizeof(vis));//初始化到达每一节点的最小步数
printf("%d\n",bfs());
}
return 0;
}
A strange lift |
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) |
Total Submission(s): 709 Accepted Submission(s): 348 |
[align=left]Problem Description[/align]There is a strange lift.The lift can stop can at every floor as you want, and there is a number Ki(0 <= Ki <= N) on every floor.The lift have just two buttons: up and down.When you at floor i,if you press the button "UP" , you will go up Ki floor,i.e,you will go to the i+Ki th floor,as the same, if you press the button "DOWN" , you will go down Ki floor,i.e,you will go to the i-Ki th floor. Of course, the lift can't go up high than N,and can't go down lower than 1. For example, there is a buliding with 5 floors, and k1 = 3, k2 = 3,k3 = 1,k4 = 2, k5 = 5.Begining from the 1 st floor,you can press the button "UP", and you'll go up to the 4 th floor,and if you press the button "DOWN", the lift can't do it, because it can't go down to the -2 th floor,as you know ,the -2 th floor isn't exist. Here comes the problem: when you is on floor A,and you want to go to floor B,how many times at least he havt to press the button "UP" or "DOWN"? |
[align=left]Input[/align]The input consists of several test cases.,Each test case contains two lines. The first line contains three integers N ,A,B( 1 <= N,A,B <= 200) which describe above,The second line consist N integers k1,k2,....kn. A single 0 indicate the end of the input. |
[align=left]Output[/align]For each case of the input output a interger, the least times you have to press the button when you on floor A,and you want to go to floor B.If you can't reach floor B,printf "-1". |
[align=left]Sample Input[/align]5 1 5 3 3 1 2 5 0 |
[align=left]Sample Output[/align]3 |
[align=left]Recommend[/align]8600 |
广搜题。在一维的情况下,求从起点到终点的最小步数。这道题有一下特点:
1)没有涉及障碍物的概念。也就是说每一点理论上都可以到达。在做搜索的题目的时候,一般都会有map[][]矩阵和vis[][]。前者用于存储整张地图的信息,如那些是路,那些事障碍物,公主(终点)在哪里,你(起点)在哪里。后者用于标记到达某一节点是的最小步数(个人习惯,这里的vis[][]是int类型的)。因为这道题中没有障碍物的概念,所以我们其实并不需要开一个map[][]数数组。
2)这道题是一维的。所以开vis数组的时候开到一维的就可以了。
3)每一点的步长不一样。之前我们接触的题目,大部分都是只能到达相邻节点,而这道题中,我们身处第一层的时候,有可能我们就只能直接到第三层,而不是到第二层。其实这也是由这道题中的“一维”的这个概念所限制的。你想想,如果在一位的情况下,每一节点只能到达相邻节点,那么在第一层就只能去到第二层。那么样例中所说的从第一层到第5层就之恩能够使一层一层的上了,就不是所谓的搜索题目了,因为在这种情况下按(5-1)次按钮就能到达指定楼层。
需要注意的是,从某一楼层出发以后,很可能不再回到该楼层,否则就死循环了。
代码如下:
/*
* d.cpp
*
* Created on: 2015年2月17日
* Author: Administrator
*/
#include <iostream>
#include <cstdio>
#include <queue>
using namespace std;
const int maxn = 205;
const int inf = 999999;
int vis[maxn];//用于标记访问有一个节点的最小步数
int dir[maxn];//某一个节点移到下一个节点的步长
int n;//节点的个数
int start;//起点
int end;//终点
struct Node{//节点
int floor;//用于标记现在位于第几层
int step;//到达现在这个位置所需要的步数
friend bool operator<(Node a,Node b){//用于实现在在优先队列中从小到大排序
return a.step > b.step;
}
};
/**
* 判断下一届点是否合法
*/
bool check(int floor){
if(floor < 0 || floor >= n){//判断当前楼层是否合法
return false;
}
return true;//表示当前楼层合法
}
int bfs(){
priority_queue<Node> q;
//初始化根节点
Node root;
root.floor = start;
root.step = 0;
Node k;
q.push(root);//根节点入队
while(!q.empty()){//如果队列非空
Node a = q.top();//每次去除対首元素
q.pop();
if(a.floor == end){//如果已经达到终点
return a.step;//返回到达终点所需要的步数
}
//第一个方向
k.floor = a.floor + dir[a.floor];//计算下一节点的位置
if(check(k.floor) == true){//如果下一节点的位置合法
k.step = a.step+1;//计算到达下一节点所需要的步数
if(vis[k.floor] > k.step){//如果之前到达目标节点所需要的步数>目前到达目标节点所需要的步数
vis[k.floor] = k.step;//更新到达当前节点所需要的最小步数
q.push(k);//将该元素入队
}
}
//第二个方向
k.floor = a.floor - dir[a.floor];
if(check(k.floor) == true){
k.step = a.step+1;
if(vis[k.floor] > k.step){
vis[k.floor] = k.step;
q.push(k);
}
}
}
return -1;//表示没有到达终点
}
int main(){
while(scanf("%d",&n)!=EOF,n){
scanf("%d%d",&start,&end);
start -= 1;//这里需要注意一下.位置我这里是从0来时算的
end -= 1;
int i;
for(i = 0 ; i < n ; ++i){
scanf("%d",&dir[i]);//初始化每一楼层的步长
}
memset(vis,inf,sizeof(vis));//初始化到达每一节点的最小步数
printf("%d\n",bfs());
}
return 0;
}
相关文章推荐
- (hdu step 4.2.3)Knight Moves(求从起点是否能够到达终点的最小步数)
- (hdu step 4.2.3)Rescue(求从起点到终点的最少步数,遇到特殊节点需要耗时2秒)
- (step4.2.4)hdu 1548(A strange lift——BFS)
- (hdu step 5.1.4)Farm Irrigation(在两个节点合并有限制条件的情况下,求集合的个数)
- (hdu step 4.2.7)逃离迷宫(在有转弯次数的限制的情况下,判断一个点是否能到另一个点)
- (hdu step 4.3.1)Tempter of the Bone(在特定的时间约束下,判断是否能够从起点达到终点)
- (hdu step 6.1.7)Connect the Cities(在有的路已经修建好的情况下,求让n个点连通的最小费用)
- 期盼中求出起点到终点的最小步数
- (hdu step 6.1.6)Jungle Roads(在索引为字符索引的情况下,求让n个点连通的最小费用)
- (hdu step 8.2.2)Good Luck in CET-4 Everybody!(在限制条件为每次只能去2的次幂个石子的条件下的巴什博奕)
- (hdu step 3.2.1)Max Sum(简单dp:求最大子序列和、起点、终点)
- BFS搜索迷宫,求起点到终点的最小步数
- (hdu step 6.1.2)Eddy's picture(在只给出二维坐标点的情况下,求让n个点连通的最小费用)
- 【搜索之BFS】杭电 hdu 1548 A strange lift
- HDU 1548 A strange lift(Dijkstra、BFS、DP)
- HDU 1548 A strange lift(BFS)
- HDU 1548 A strange lift
- hdu——4341(有限制条件的dp)
- hdu 1548 A strange lift (bfs)
- A strange lift HDU 1548