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.<br>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"?<br>
Input
The input consists of several test cases.,Each test case contains two lines.<br>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.<br>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<br>3 3 1 2 5<br>0
Sample Output
3
大意:一个奇葩电梯能上能下不过只能上下每层上面的数字的层数(第一反应数字排列),然后有起点终点,求最小的步数
思路:把电梯抽象一下给定一组数据从特定的一个数字开始选中一个数字接下来只能选择特定的两个数字之一求到特定的一个数字的最小步数
抽象后题目很简单了就是搜索,并且求最小,自然是bfs每层两个选择上下入队取队首检验合法性楼层是终点结束。
代码:
#include <iostream>
#include <cstring>
#include <queue>
using namespace std;
const int MAX = 300;
int f[MAX];
bool visit[MAX];
struct Node
{
int dir, move;
};
int bfs(int a, int b,int N)
{
Node t,t1;
t.dir = a; t.move = 0;
visit[t.dir] = 1;
queue<Node>q;
q.push(t);
while (!q.empty())
{
t = q.front();
q.pop();
if (t.dir == b)
return t.move;
if (t.dir - f[t.dir] >= 1&&!visit[t.dir - f[t.dir]])
{
t1.move = t.move + 1;
t1.dir= t.dir - f[t.dir];
visit[t1.dir] = 1;
q.push(t1);
}
if (t.dir + f[t.dir] <= N && !visit[t.dir + f[t.dir]])
{ t1.move = t.move + 1;
t1.dir = t.dir + f[t.dir];
visit[t1.dir] = 1;
q.push(t1); }
}
return -1;
}
int main()
{
int N, A, B;
while (cin >> N&&N != 0)
{
memset(visit, 0, sizeof(visit));
cin >> A >> B;
for (int i = 1; i <=N; ++i)
cin >> f[i];
cout << bfs(A, B, N) << endl;
}
return 0;
}
#include <cstring>
#include <queue>
using namespace std;
const int MAX = 300;
int f[MAX];
bool visit[MAX];
struct Node
{
int dir, move;
};
int bfs(int a, int b,int N)
{
Node t,t1;
t.dir = a; t.move = 0;
visit[t.dir] = 1;
queue<Node>q;
q.push(t);
while (!q.empty())
{
t = q.front();
q.pop();
if (t.dir == b)
return t.move;
if (t.dir - f[t.dir] >= 1&&!visit[t.dir - f[t.dir]])
{
t1.move = t.move + 1;
t1.dir= t.dir - f[t.dir];
visit[t1.dir] = 1;
q.push(t1);
}
if (t.dir + f[t.dir] <= N && !visit[t.dir + f[t.dir]])
{ t1.move = t.move + 1;
t1.dir = t.dir + f[t.dir];
visit[t1.dir] = 1;
q.push(t1); }
}
return -1;
}
int main()
{
int N, A, B;
while (cin >> N&&N != 0)
{
memset(visit, 0, sizeof(visit));
cin >> A >> B;
for (int i = 1; i <=N; ++i)
cin >> f[i];
cout << bfs(A, B, N) << endl;
}
return 0;
}