标签:
题目:
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 |
Problem Description 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"? |
Input 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. |
Output 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". |
Sample Input 5 1 5 3 3 1 2 5 0 |
Sample Output 3 |
Recommend 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.4)A strange lift(求从起点到终点的最小步数,限制条件是:在一维的情况下)
标签:
原文地址:http://blog.csdn.net/hjd_love_zzt/article/details/43866921