Drizzle 面前有一条由一堆非负整数组成的道路,从第一个数字起步,每次他都能跳出不大于当前数字的距离,每个数字之间的距离为1,那么他最少需要跳多少次才能到达终点?
要求:
输入:第一行输入道路中数字的个数n也就是道路的长度,第二行输入这n个数字
下面展示一些 内联代码片
。
下面展示一些 内联代码片
。
5
2 3 1 1 4
输出:输出一个数字,表示最少跳跃次数
下面展示一些 内联代码片
。
2
解释: 跳到最后一个位置的最小跳跃数是 2。从下标为 0 跳到下标为 1 的位置,跳 1 步,然后跳 3 步到达数组的最后一个位置。
范围:
对于 20% 的数据:n≤100
对于 100% 的数据:n≤1000000
所有整数元素在int范围内
下面展示一些 内联代码片
。
下面展示一些 内联代码片
。
思路:在能跳的区间里先筛选出最大的数,再从最大的数到能跳到的区间里筛选出最优的位置,一直到能跳到终点的地方终止。
#include<iostream>
#include<vector>
using namespace std;
int main(){
int t;
cin>>t;
vector<int>v;
for(int i=0;i<t;i++){
int a;
cin>>a;
v.push_back(a);
}
int count=0;//count对需要跳几次计数
int max=0,temp2=0,max1=0;
t--;//因为从第一个开始,所以需要跳的距离减1
while(1){
max1=0;
temp2=max;
if(v[temp2]>=t){//如果能直接跳到终点,那就跳过去结束循环
count++;
break;
}
else{
max=temp2+v[temp2];//将能跳到的最远的地方max初始化成能跳到的范围中最后一个位置的下标
for(int j=temp2+1;j<=temp2+v[temp2];j++)if(v[j]>=v[max]&&v[j]+j-temp2>v[temp2])max=j;
/*在能跳到的下标(【temp2+1,temp2+v[temp2]】筛选出最大的数)
且这个数能跳出这个范围*/
max1=v[max]+max;//储存第一个for循环中跳到的位置
for(int j=max;j<=temp2+v[temp2];j++)
//再次在最大的数和结尾筛选出最远的 ,因为仅仅是最大的并不能满足跳的最优
//没有这个的话最后两个测试点是错的
{
if(v[j]+j>max1){
max1=v[j]+j;
max=j;
}
}
t-=max-temp2;//跳完剩余的距离
count++;//步数加1
}
}
cout<<count;
return 0;
}