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;
}