https://nanti.jisuanke.com/t/18
- 时间限制 1000ms
- 内存限制 65536K
题目描述
给定一个非负整数数组,假定你的初始位置为数组第一个下标。
数组中的每个元素代表你在那个位置能够跳跃的最大长度。
请确认你是否能够跳跃到数组的最后一个下标。
例如:A = [2,3,1,1,4] 能够跳跃到最后一个下标,输出true
;
A = [3,2,1,0,4] 不能跳跃到最后一个下标,输出false
。
输入格式
第一行输入一个正整数 n(1≤n≤500),接下来的一行 n 个整数,输入数组 Ai。
输出格式
如果能跳到最后一个下标,输出true
,否则输出false
。
样例输入
5
2 0 2 0 1
样例输出
true
解题思路
贪心思想:
方法一:从前往后找。我们可以找到第一个可以直接跳到最后一个地方的点,然后把这个地方作为最后一个点(这个点能到最后一个,那么只要能到这个点就能到最后一个),一直循环,看看0这个地方能否作为最后一个点,如果能则输出true,否则输出false。
#include <stdio.h>
int main() {
int n, a[510];
while (~scanf("%d", &n)) {
for (int i = 0; i < n; i++)
scanf("%d", &a[i]);
n--;
for (int i = 0; i < n; i++) {
if (i + a[i] >= n) {
n = i;
i = -1;
}
}
if (n)
printf("false\n");
else printf("true\n");
}
return 0;
}
方法二:从后往前找。我们可以找到最后一个可以直接跳到最后一个地方的点,然后把这个地方作为最后一个点(这个点能到最后一个,那么只要能到这个点就能到最后一个),一直循环,看看0这个地方能否作为最后一个点,如果能则输出true,否则输出false。
#include <stdio.h>
int main() {
int n, a[510];
while (~scanf("%d", &n)) {
for (int i = 0; i < n; i++)
scanf("%d", &a[i]);
n--;
for (int i = n - 1; i >= 0; i--)
if (i + a[i] >= n)
n = i;
if (n)
printf("false\n");
else printf("true\n");
}
return 0;
}
方法三:用MaxStep存当前跳跃的最大距离,循环遍历出当前跳跃的最大距离。看看最后最大距离是否大于等于n,如果大于等于n则证明能到达最后一个,否则不能。
#include <cstring>
#include <iostream>
using namespace std;
int main() {
int n, a[510], maxstep;
while (cin >> n) {
for (int i = 0; i < n; i++)
cin >> a[i];
maxstep = a[0];
for (int i = 0; i < n; i++) {
if (i > maxstep) {//跳跃的最大距离小于i,证明到达不了i,则肯定到不了最后
printf("false\n");
break;
}
maxstep = max(maxstep, i + a[i]);
if (maxstep >= n - 1) {//跳跃的最大距离大于等于n,则肯定能到达最后
printf("true\n");
break;
}
}
}
return 0;
}