华为实习生面试题-跳跃比赛 C++实现

师兄参加了华为的实习生招聘,我也蹭了一下热闹。

一、题目描述

给出一组正整数,你从第一个数向最后一个数方向跳跃,每次至少跳跃1格,每个数的值表示你从这个位置可以跳跃的最大长度。计算如何以最少的跳跃次数跳到最后一个数。

输入描述

第一行表示有多少个数n

第二行开始依次是1到n个数,一个数一行

输出描述

输出一行,表示最少跳跃次数。

示例1

输入

7

2

3

2

1

2

1

5

输出

3

说明

7表示接下来要输入7个正整数,从2开始。数字本身代表可以跳跃的最大步长,此时有2种跳法,为2-2-2-5和2-3-2-5都为3步。

二、分析

一开始看到这题就觉得难受,好麻烦的题目,师兄和我说是用动态规划做,要写出迭代方程什么的。

仔细想过之后,想起运筹学中确实是这么解这一类题的,不过那是把方案一起解出来了——也就是题中的“2-2-2-5和2-3-2-5”。可是题目要求的答案只是“最少跳跃次数”,并没有说要给出方案,说明还是可以取巧的。

先整理一下规律,假设第i步到达了第k个位置(从0开始编号),那么前面所有的位置应该都能在第i步或第i步之前到达,在下图中标为橙色。


下面开始走一边用例。第0步,此时能到达的点就是起点,所以也就第一个点被标记。同时可以计算出下一step能到达的最远位置为2(第一个格子的位置0 + 该格中的数字2),也就是从左到右数第3个格子,接下来把能到达的格子涂色。


更进一步。在橙色区域循环,计算出下一步最远能到达的点,第二个格子和第三个格子都符合要求,继续把能到达的格子标为橙色。


那么什么时候可以停止循环呢?很简单,只要最后一个格子变成橙色就结束循环了,也就是STEP_max >= n-1。


当然,当step=3时,就得到想要的结果了,此时也知道了最少需要跳跃3次才能到达终点。


以上的式子都是基于从0编号这一条件的,所以编程时我也从0开始编号。

三、解答

就直接贴上代码啦

#include <iostream>
#include <vector>

using namespace std;

int main()
{
	// 先读入数据
	int len = 0;
	cin >> len;
	vector<int> data(len);
	for (int i = 0; i < len;i++) {
		cin >> data[i];
	}

	// 循环,当到达末尾时跳出循环
	int step = 0;
	int out = 0;
	int step_max = 0;
	while (true) {
		step++;
		for (int j = 0; j <= out; j++) {
			if (data[j] + j > step_max) {
				step_max = data[j] + j;
			}
		}
		out = step_max;
		if (out + 1 >= len) {
			break;
		}
	}

	// 输出结果
	cout << step << endl;
	system("pause");
    return 0;
}

转载请注明出处,谢绝盈利性质的转载。

猜你喜欢

转载自blog.csdn.net/hewhys/article/details/79888315