标题: D - 跳石头
题目名字
D - 跳石头
[题目链接]P2678 [NOIP2015 提高组] 跳石头 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
题意
两块岩石作为比赛起点和终点。在起点和终点之间,有 N 块岩石(不含起点和终点的岩石)。在比赛过程中,选手们将从起点出发,每一步跳向相邻的岩石,直至到达终点。使得选手们在比赛过程中的最短跳跃距离尽可能长。组委会至多从起点和终点之间移走 M块岩石(不能移走起点和终点的岩石)。
思路
- 先找到裁判员,需要移走的石头,是哪几块。
- 再利用二分把运动员需要跳的最短的石头距离求出来。
坑点
- 不好判别,需要移走的石头是哪几块?
2 不好找到用二分的地方.
算法一:c++
时间复杂度
普及/提高−
实现步骤
- 找到石头,并把石头移走.
- 用二分把运动员需要跳的最短的石头距离求出来。
代码
#include<cstdio>
#include<algorithm>
#define N (50000+10)
using namespace std;
int a[N];
int d,n,m,ans;
bool check(int dis){
int count=0,i=0,last=0;
while (i<n+1){
i++;
if (a[i]-last<dis){//如果距离小于,那么这块石头需要搬走
count++;
}
else{
last=a[i];
}
}
if (count>m) return 0;
else return 1;
}
int main(){
scanf("%d%d%d",&d,&n,&m);
for (int i=1;i<=n;i++) scanf("%d",&a[i]);
a[n+1]=d;
int l=1,r=d,mid;
while (l<=r){
mid=(l+r)/2;
if (check(mid)){
ans=mid;
l=mid+1;
}
else r=mid-1;
}
printf("%d",ans);
}
总结
我们要找好每一步的要求,有些要求可能隐藏在题目里面,需要把这个要求做完才能利用我们所学的知识往下一步走。