小红的数组操作(经典二分操作)

链接:https://ac.nowcoder.com/acm/contest/71993/D
来源:牛客网

小红拿到了一个数组,她每次可以进行如下操作:
选择一个数,使其减去 \(x\)
小红希望\(k\)次操作之后,该数组的最大值尽可能小。请你求出这个尽可能小的最大值。
输入描述:
第一行输入三个正整数 \(n\)\(k\)\(x\),代表数组长度、操作次数以及每次操作减的数。
第二行输入 \(n\) 个正整数\(a_i\),代表小红拿到的数组。

\(1\leq n \leq 10^5\)
\(1\leq a_i,k,x \leq 10^9\)
输出描述:
一个整数,代表 \(k\) 次操作后,数组尽可能小的最大值。
示例1
输入
5 3 5
4 3 11 2 1
输出
3
说明
第一个数操作 1 次,第三个数操作 2 次,数组变成 [-1,3,1,2,1],最大值为 3。

经典二分,不多解释

#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
const int maxn=1e5+100;
ll n,k,x;
ll a[maxn];
bool check(ll ma){
	ll z=0;
	for(int i=1;i<=n;i++){
		if(a[i]>ma){
			z+=((a[i]-ma)/x);
			if((a[i]-ma)%x>0){
				z++;
			}
		}
		if(z>k){
			return false;
		}
	}
	return k>=z;
}
int main(){
	cin>>n>>k>>x;
	for(int i=1;i<=n;i++){
		cin>>a[i];
	}
	ll l = -1e18,r = 1e9,ans;
	while(r>=l){
		ll mid=(l+r)/2;
		if(check(mid)){
			r=mid-1;
			ans=mid;
		}else{
			l=mid+1;
		}
	}
	cout<<ans<<endl;
	return 0;
}
posted @ 2023-12-23 21:26  lipu123  阅读(1433)  评论(0)    收藏  举报