洛谷P1676 [USACO05FEB] Aggressive cows G 题解
本题做法
- 二分,贪心。
思路
我们可以二分最大化答案 \(x\),每次使用 \(check\) 函数测试当前二分的答案是否正确。
\(check\) 函数:定义变量 \(cnt\) 和 \(nxt\),分别代表当前答案可以放置的牛数量以及下一个符合当前答案的位置。初始时,\(cnt=1,nxt=a[1]+mid\)。为什么 \(nxt\) 是 \(a[1]+mid\) 呢?因为只有在 \(a[1]+mid\) 的地方放下一头牛,才可以符合当前答案 \(mid\)。然后 for 循环遍历 \(a\),若 \(a[i]<nxt\),则代表当前位置不可以放置牛,直接 continue
。否则就 \(cnt++\),\(nxt=a[i]+mid\)。最后返回 \(cnt\) 是否大于等于 \(mid\) 即可。
代码
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+5;
int n,m,a[N];
inline bool check(int mid){
int cnt=1,nxt=a[1]+mid;
for(int i=1;i<=n;i++){
if(a[i]<nxt) continue;
cnt++;
nxt=a[i]+mid;
}
return (cnt>=m);
}
int main(){
cin>>n>>m;
for(int i=1;i<=n;i++) cin>>a[i];
sort(a+1,a+1+n);
int l=0,r=1e9;
while(l+1<r){
int mid=l+(r-l)/2;
if(check(mid)) l=mid;
else r=mid;
}
cout<<l<<endl;
return 0;
}