题目描述
呵呵,有一天我做了一个梦,梦见了一种很奇怪的电梯。大楼的每一层楼都可以停电梯,而且第i层楼(1≤i≤N)上有一个数字K_i(0≤Ki≤N)。
电梯只有四个按钮:开,关,上,下。上下的层数等于当前楼层上的那个数字。当然,如果不能满足要求,相应的按钮就会失灵。
例如:3, 3 ,1 ,2 ,5代表了K_i(K_1=3,K_2=3,…),从1楼开始。在1楼,按“上”可以到4楼,按“下”是不起作用的,因为没有−2楼。
那么,从A楼到B楼至少要按几次按钮呢?
输入格式
共二行。
第一行为3个用空格隔开的正整数,表示N,A,B(1≤N≤200, 1≤A,B≤N)
第二行为N个用空格隔开的非负整数,表示K_i。
输出格式
一行,即最少按键次数,若无法到达,则输出-1。
输入输出样例
输入
5 1 5
3 3 1 2 5
输出
3
我的解法
1 #include<bits/stdc++.h> 2 using namespace std; 3 4 int n, a, b,k[210]; 5 bool f[210] = { false }; 6 7 void bfs() { 8 queue<pair<int,int> > q; 9 pair<int, int> p,t; 10 p.first = a; p.second = 0; 11 q.push(p); 12 while (!q.empty()) { 13 p = q.front(); q.pop(); 14 if (f[p.first]) 15 continue; 16 f[p.first] = true; 17 if (p.first == b) { 18 cout << p.second; 19 return; 20 } 21 if (p.first - k[p.first] > 0) { 22 t.first = p.first - k[p.first]; 23 t.second = p.second+1; 24 q.push(t); 25 } 26 if (p.first + k[p.first] <= n) { 27 t.first = p.first + k[p.first]; 28 t.second = p.second+1; 29 q.push(t); 30 } 31 } 32 cout << -1; 33 } 34 35 int main() { 36 cin >> n >> a >> b; 37 for (int i = 1; i <= n; i++) 38 cin >> k[i]; 39 bfs(); 40 }
用时32ms
广度优先搜索算法的思路:
1、对于初始状态入队,设置初始状态为已访问
2、如果队列不为空时,出队队头元素,否则跳到第5步
3、检查出队的元素是否为最终解,如果是则跳到第5步。
4、对于出队的元素,检查所有相邻状态,如果有效并且未访问,则将 所有有效的相邻状态进行入队,并且设置这些状态为已访问,然后 跳到第2步重复执行
5、检查最后出队的元素是否为最终解,如果是输出结果,否则说明无解
广度优先搜索算法的关键是要搞清楚求解过程中每一步的相邻状态有哪些, 每个状态需要记录什么信息,在搜索过程中如何标记这些状态为已访问。