题目:To Add or Not to Add(思维+前缀和区间问题)

版权声明:本文为博主原创文章,欢迎转载。如有问题,欢迎指正。 https://blog.csdn.net/weixin_42172261/article/details/88343706

A piece of paper contains an array of n integers a1, a2, …, an. Your task is to find a number that occurs the maximum number of times in this array.
However, before looking for such number, you are allowed to perform not more than k following operations — choose an arbitrary element from the array and add 1 to it. In other words, you are allowed to increase some array element by 1 no more than k times (you are allowed to increase the same element of the array multiple times).
Your task is to find the maximum number of occurrences of some number in the array after performing no more than k allowed operations. If there are several such numbers, your task is to find the minimum one.
Input
The first line contains two integers n and k (1 ≤ n ≤ 105; 0 ≤ k ≤ 109) — the number of elements in the array and the number of operations you are allowed to perform, correspondingly.
The third line contains a sequence of n integers a1, a2, …, an (|ai| ≤ 109) — the initial array. The numbers in the lines are separated by single spaces.
Output
In a single line print two numbers — the maximum number of occurrences of some number in the array after at most k allowed operations are performed, and the minimum number that reaches the given maximum. Separate the printed numbers by whitespaces.
思路:
因为当个数相同时小数优先,所以肯定先要从小到大排序。增加1的次数要小于等于k次,也就是被增加的那几个数增加的总和要小于等于k。先用前缀和来记录sum[i],然后从i=2开始,判断i的前几个数都变成a[i]这个数需要增加的总和:如果a[i]*(i-begin)-(sum[i]-sum[begin])>k说明当从begin+1开始到i都变成a[i]需要增加的总和大于k不满足条件,所以being++。
代码:

#include <iostream>
#include <cstdio> 
#include <cmath>
#include <algorithm>
typedef long long ll;
using namespace std;

ll sum[100005], a[100005];
int main()
{
	ll n, k;
	scanf("%lld %lld", &n, &k);
	for (ll i=1; i<=n; i++)
		scanf("%lld", &a[i]);
	sort(a+1, a+n+1);
	for (ll i=1; i<=n; i++)
		sum[i]=sum[i-1]+a[i];
	ll times=1, number=a[1], begin=0;
	for (ll i=2; i<=n; i++){
		//从begin+1到i的个数*a[i]-sum[i]就是变成a[i]需要增加1的次数 
		while (a[i]*(i-begin)-(sum[i]-sum[begin])>k)
			begin++;
		if (i-begin>times){
			times=i-begin;
			number=a[i];
		}
	}
	printf("%lld %lld", times, number); 
	return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_42172261/article/details/88343706
Add