P2672跳石头
这是2015noip的一道二分答案的题目,看了题解才会,,
题目给出石头的位置并且让你踩着石头往前跳,最多删掉m个石头还可以顺利通过,求解最短跳跃距离的最大值。
那么二分什么呢:mid为跳跃的长度。那么left=0,right=l进行二分.再拿s和now分别记录当前搬走的石头数量,判断是否可以跳过去(用类似前缀和的思想)。最后当前跳跃使得搬走的石头>=m,那么则让right=mid-1,如果搬走的<=m,那么就记录下当前的mid,left=mid+1。又因为题目说的是最小距离的最大值,那么最后找到的则是最大的。
1.明确什么题目可以用二分 eg.最大的最小,k优,关键量具有单调性,最小平均路。。
2.二分什么求解什么
3.怎么来改变二分的左右端点
4.仔细读题,看好至多至少等关键字,把逻辑搞清楚
#include<iostream> #include<cmath> #include<cstring> #include<string> #include<algorithm> #include<cmath> #include<cstdio> #define maxn 600000 using namespace std; int m,n; int l,d; int left,right,mid; int a[maxn]; int s,now; int ans=0; int main(){ cin>>l>>n>>m; for(int i=1;i<=n;i++){ cin>>a[i]; } int left=0,right=l; while(left<=right){//二分跳跃长度 mid=(left+right)/2; now=0;//跳到第几个 s=0;//搬了几个石头 for(int i=1;i<=n;i++){ if(a[i]-a[now]<mid){//假如跳过去了 s++; //搬走 } else{ now=i; } } if(s<=m){ ans=mid; left=mid+1; } else right=mid-1; } cout<<ans; return 0; }
待到oi十一月,我花开后百花杀。