SDNU-BFS——D - A strange lift

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 are on floor A,and you want to go to floor B,how many times at least he has 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

BFS常用来求最短路问题,这一点虽然dfs也可以做到,但明显bfs更容易实现

BFS求最短路要用到队列,一般还是结构体队列,因为要保存步数和下一个节点

像这一个题再每一层可上可下这样都可以导入到队列中去

队列嘛,先进先出,所以出队列还是有顺序的你可以保证每一种情况都能考虑到

并且每一种情况一次都会进行一次动作(不像dfs非得全进行完)

所以同步进行,率先符合条件的一定是最快的

PS:为了防止死循环要有一个vis判断数组

其余的就是常规的bfs了

#include  
#include  
#include  
#include  
#include  
#include  
#include  
using namespace std;  
const int MAX = 200 + 10;  
bool vis[MAX];
struct Fd  
{  
    int to;	
	int step;  
} fd,nextfd;
queue fq;
int fr[MAX];
 
int main()
{
	int m,a,b,i;
	while(scanf("%d",&m) , m)
	{
		memset(vis,0,sizeof(vis)); 
		cin>>a>>b;
		for(i = 1;i <= m;i++)
		{
			cin>>fr[i];
		}
		
		while(!fq.empty()) //清空队列 
        {  
            fq.pop();  
        }  
        int  t1 ,t2,flag=0;
        fd.step=0; 
        fd.to=a; 
		fq.push(fd);  
    	vis[fd.to]=1;
		while(!fq.empty())  
        {  
            fd = fq.front();//取出首元素  
            fq.pop();  
            if(fd.to == b)//如果到达终点  
            {  
                printf("%d\n",fd.step);  
                flag=1;  
                break;  
            }  
            t1 = fd.to + fr[fd.to];//向上走  
            if(t1 <= m && !vis[t1])  
            {  
  
                vis[t1]=1;  //表示走过 
                nextfd.to=t1;  
                nextfd.step=fd.step+1;  
                fq.push(nextfd);  
            }  
            t1=fd.to - fr[fd.to];//向下走  
            if(t1 >= 1&& !vis[t1] )  
            {  
                vis[t1]=1;  
                nextfd.to = t1;  
                nextfd.step=fd.step+1;  
                fq.push(nextfd);  
            }  
        }  
        if(!flag)//如果走不到  
            printf("-1\n");  
    }  
		
	return 0;
}




你可能感兴趣的:(oj)