2020年CSP-X复赛真题及题解(T2:勇敢的津津)
题目描述
津津是个勇敢的孩子,总是做一些挑战自己的事情。一天津津来到一条宽为 L L L 米的小河边,河道的一边到另一边需要途径 N N N 块较大的石墩,每块石墩到这一边岸边之间距离 d i d_i di 米(石墩不占距离,只考虑石墩的中间点到这一边岸边之间距离)。津津想踩着这些石墩从小河的这一边跳到另一边(不落入水中),一次可以跳过几块石墩。已知津津每次最多跳 M M M 米的距离,那么津津最少跳几次就能从这一边跳到另一边?
输入格式
第一行包含三个整数 L , N , M L,N,M L,N,M,分别小河的宽度、石墩数和津津跳的最远距离。
接下来 N N N 行,每行一个整数,第 i i i 行的整数 d i ( 0 < d i < L ) d_i(0\lt d_i \lt L) di(0<di<L),表示第 i i i 块石墩与这一边岸边的距离,保证石墩之间的距离和最靠边的石墩到这一边岸边的距离小于等于 M M M。这些石墩按与起点距离从小到大的顺序给出,且不会有两个石墩出现在同一个位置。
输出格式
一个整数,即最少的跳跃次数。
输入输出样例 1
输入 1
10 4 2
2
4
6
8
输出 1
5
输入输出样例 2
输入 2
25 5 10
2
11
14
17
21
输出 2
4
说明/提示
【样例解释】
样例一:津津可以从岸边跳到距离为 2 2 2 的石墩上,然后跳到距离为 4 4 4 的石墩上,再跳到距离为 6 6 6 的石墩上,再跳到距离为 8 8 8 的石墩上,最后跳到对岸。总共 5 5 5 跳跃。
样例二:津津可以从岸边跳到距离为 2 2 2 的石墩上,然后跳到距离为 11 11 11 的石墩上,再跳到距离为 21 21 21 的石墩上,最后跳到对岸。总共 4 4 4 跳跃。
【数据范围】
对于 30 % 30\% 30% 的数据, 1 ≤ N ≤ 10 1\leq N\leq 10 1≤N≤10。
对于 50 % 50\% 50% 的数据, 1 ≤ N ≤ 100 1\leq N\leq 100 1≤N≤100。
对于 100 % 100\% 100% 的数据, 1 ≤ N ≤ 500 1\leq N\leq 500 1≤N≤500, 1 ≤ M , L ≤ 10 6 1\leq M,L\leq 10^6 1≤M,L≤106。
思路分析
本题可用贪心 策略求解:
从起点出发,每次跳跃都选择当前能到达的最远石墩 (或直接跳到对岸),因为跳得越远,剩余距离越短,所需总跳跃次数必然不会增加。
具体实现时,在每一步先判断能否直接跳到对岸 p o s + M > = L pos + M >= L pos+M>=L,若能则直接跳,结束;否则遍历所有石墩,找到满足 p o s < d i < = p o s + M pos < d_i <= pos + M pos<di<=pos+M 且下标最大的石墩(即最远的一个),跳到该处。重复此过程,直到到达对岸,累计跳跃次数即为最少次数。
代码实现
cpp
#include<bits/stdc++.h>
using namespace std;
int L,N,M;
int a[510]; // 石墩位置数组(最多500个)
int main(){
cin>>L>>N>>M; // 河宽、石墩数、最远跳距
for(int i=0;i<N;i++) cin>>a[i]; // 读入石墩距离
int pos=0, cnt=0; // 当前位置,跳跃次数
while(pos<L){//未到达对岸
// 如果可以直接跳到对岸,立即跳过去并结束
if(pos + M >= L){
pos = L;
cnt++;
break;
}
// 否则寻找最远的可达石墩
int nxt = -1; // 最远可达石墩的下标,-1表示不存在
for(int i=0;i<N;i++){
if(a[i] > pos && a[i] <= pos + M)
nxt = i; // 因为a递增,遍历到的最后一个就是最远的
}
pos = a[nxt]; // 跳到最远的石墩
cnt++;
}
cout<<cnt; // 输出最少跳跃次数
return 0;
}
功能分析
- 输入处理 :使用
cin读取三个整数和N个递增的石墩位置。 - 贪心决策:每次迭代先检查能否直达终点,能则直接跳转结束;否则在石墩中选最远可达的落脚点,保证每一步都最大化前进距离。
- 终止条件 :当
pos达到或超过L(即到达对岸)时循环停止,输出累计的跳跃次数。 - 时间复杂度 :每次跳跃最多遍历所有
N个石墩,跳跃次数最坏为N+1,故复杂度为O(N²),但N≤500,完全可行。 - 空间复杂度 :仅使用固定大小数组,为
O(N)。
更多内容请关注专栏:信奥赛C++普及组csp-j初赛&复赛真题题解(持续更新): https://blog.csdn.net/weixin_66461496/category_12808781.html 点击跳转
【秘籍汇总】(完整csp信奥赛C++学习资料):
1、csp/信奥赛C++,完整信奥赛系列课程(永久学习):
https://edu.csdn.net/lecturer/7901 点击跳转

2、CSP信奥赛C++竞赛拿奖视频课:
https://edu.csdn.net/course/detail/40437 点击跳转

https://edu.csdn.net/course/detail/41081 点击跳转

3、csp信奥赛高频考点知识详解及案例实践:
CSP信奥赛C++动态规划:
https://blog.csdn.net/weixin_66461496/category_13096895.html点击跳转
CSP信奥赛C++标准模板库STL:
https://blog.csdn.net/weixin_66461496/category_13108077.html 点击跳转
信奥赛C++提高组csp-s知识详解及案例实践:
https://blog.csdn.net/weixin_66461496/category_13113932.html 点击跳转
4、csp信奥赛冲刺一等奖有效刷题题解:
信奥赛C++普及组CSP-J一等奖通关刷题题单及题解:
https://blog.csdn.net/weixin_66461496/category_12673810.html 点击跳转
信奥赛C++普及组csp-j初赛&复赛真题题解(持续更新): https://blog.csdn.net/weixin_66461496/category_12808781.html 点击跳转
信奥赛C++提高组csp-s初赛&复赛真题题解(持续更新):
https://blog.csdn.net/weixin_66461496/category_13125089.html 点击跳转
5、GESP C++考级真题题解:

GESP(C++ 一级+二级+三级)真题题解(持续更新):https://blog.csdn.net/weixin_66461496/category_12858102.html 点击跳转

GESP(C++ 四级+五级+六级)真题题解(持续更新):https://blog.csdn.net/weixin_66461496/category_12869848.html 点击跳转

GESP(C++ 七级+八级)真题题解(持续更新):
https://blog.csdn.net/weixin_66461496/category_13117178.html 点击跳转
· 文末祝福 ·
cpp
#include<bits/stdc++.h>
using namespace std;
int main(){
cout<<"跟着王老师一起学习信奥赛C++";
cout<<" 成就更好的自己! ";
cout<<" csp信奥赛一等奖属于你! ";
return 0;
}
