1、链接
http://acm.hrbust.edu.cn/index.php?m=ProblemSet&a=showProblem&problem_id=2337
2、题目:
Description
小t又遇见问题了,你肯定还会帮她的对吧?
给出一个数组(只含有正整数),现假设你在数组的第一个位置,数组的每个值表示在当前位置你可以跳的最大步数。
如a2=3,表示你在下标为2的位置时,一次最多可以跳3步。现在你想跳到数组的最后一个位置,问最少要跳多少次?多少次不是多少步…
Input
有多组输入数据,每组数据第一行输入一个正整数n(1≤n≤30000),第二行输入n个整数ai(0≤ai≤109),含义如题。
Output
对于每组输入数据,输出小t跳到数组最后的位置需要跳的最少次数,每组输出占一行。
Sample Input
5
2 3 1 1 4
2
1000 1
Sample Output
2
1
Hint
1.对于样例1,到达4位置最少要跳2次。
第一次:从0位置跳到1位置;
第二次:跳3步跳到最后位置。
2.数据保证你一定能跳到最后位置。
Source
"华为杯"2017级程序设计竞赛(热身)
3、解法
贪心,每次跳到这个区间范围内最大的值判断是否 > =最后一个位置
4、代码:
法一:模拟了一次T了
#include<iostream> #include<stdio.h> #include<math.h> #include<string.h> using namespace std; const int maxn = 30005; int b[maxn]; int ans(int a[], int len) { int res = 1; if(a[0] >= len-1) { res = 1; } else { for(int k = 0; k < len ;) { int tmp = a[k]; int maxx = -99; int j; int tt = 0; for(int i = k; i <= (tmp + k); i++) { if(a[i] > maxx) { maxx = a[i]; j = i; } } if(maxx >= len - 1 - j) { res++; break; } else { k += j; res++; } } } return res; } int main() { int n; while(~scanf("%d",&n)) { for(int i = 0; i < n ; i++) { scanf("%d",&b[i]); } int step = ans(b,n); printf("%d\n",step); } return 0; } /*in 5 2 3 1 1 4 2 1000 1 7 2 4 3 7 6 5 8 8 1 3 2 4 7 8 9 10 out 2 1 3 3 */
法二:
#include<bits/stdc++.h> using namespace std; const int maxn = 30005; int n; int Step(int a[]) { int l = 0; int r = 0; int ans = 0; while(r < n - 1){ int maxx = -999; for(int i = l; i <= r; i++) { maxx = max(maxx,i+a[i]); } /*更新左右区间 找到之前maxx长度范围内的maxx后,下一次更新的区间是(r+1,maxx) 比如: 数组:1 3 2 4 7 8 9 9 下标:0 1 2 3 4 5 6 7 条件: r < 10 - 1 l = 0 r = 0 l ~ ~ r maxx = 1; l = 1 r = 1 ans++; l ~ ~ r maxx = 4; l = 2 r = 4 ans++; l ~ ~ r maxx = 11; l = 5 r = 11 ans++ */ l = r+1; r = maxx; ans++; } return ans; } int main() { int a[maxn]; while(~scanf("%d",&n)) { for(int i = 0; i <n; i++) scanf("%d",&a[i]); int ans = Step(a); printf("%d\n",ans); } return 0; } /*in 5 2 3 1 1 4 2 1000 1 7 2 4 3 7 6 5 8 8 1 3 2 4 7 8 9 10 out 2 1 3 3 */