题目链接:
https://www.luogu.com.cn/problem/P2678
解题思路:
对可能的答案范围进行二分。
对 [ 1 , L ] \large [1,L] [1,L]内值进行二分,若该搬出所有小于等于该距离石头的数量 c n t \large cnt cnt超过预期 m \large m m,则二分减小;否则二分增大。
代码
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<string>
#include<vector>
#include<queue>
#include<cmath>
#include<set>
#define INF 0x3f3f3f3f
typedef long long ll;
using namespace std;
int dis,n,m;
const ll MAX_SIZE = 1e5+5;
int stones[MAX_SIZE]={0};
int tap[MAX_SIZE]={0};
int chck(int distance){
//查询搬出所有 小于等于distance间距的石头是否可行。
int cnt=0,pre=0;
for(int i=1;i<=n+1;i++){
if(stones[i]-pre<=distance) cnt++;
else pre=stones[i];
}
if(cnt>m) return 1;
else return 0;
}
int main() {
int l,r,mid;
cin >> dis >> n >> m;
//输入的时候记得把n+1给记上。
for(int i=1;i<=n;i++)
cin >> stones[i];
stones[n+1]=dis;
//二分初始化
l=1,r=dis,mid =(l+r)/2;
//开始二分
while(l<r){
if(chck(mid)==1){ //超预算了(即删多了)。
r=mid;
mid=(l+r)/2;
}
else{
l=mid+1;
mid=(l+r)/2;
}
}
cout << mid;
}