【代码超详解】Codeforces 1328F. Make k Equal(暴力)

传送门

一、题目描述

二、算法分析说明与代码编写指导

要求凑出至少 k 个数相同,题目只允许两种方式:
1、每次选一个最小值,将其 +1;
2、每次选一个最大值,将其 -1。
每个最值都改变完后,才可以选下一个改变。所以,我们不妨模拟这个过程。
首先如果已经有某个数出现了至少 k 次,那么直接输出 0。
如果没有,则将数组从小到大排序,然后以将每一个数 a1,a2,……,an 都调整为至少出现 k 次为目标。
设要通过这两种方式最终使得 ai 出现 n 次。那么可以有三种方式调整:
①仅将 a1,a2,……,ai-1 每次都增加 1,直到全部变成 ai。
于是最后共有 i 个 ai。分类讨论:
【1】如果 i < k,那么这种调整方法不符合要求,不计入答案。
调整花费的总次数:
在这里插入图片描述
【2】如果 i >= k,则扣掉最后 i - k 次调整。也就是说等效于从 a1 开始不断增加当前最小的数到 ai,增加到出现 k 个 ai 时就停止。
②仅将 ai+1,……,an 每次都减去 1,直到全部变成 ai。
调整花费的总次数:
在这里插入图片描述
于是最后共有(n - i + 1)个 ai 。分类讨论:
【1】如果 n - i + 1 < k,那么这种调整方法不符合要求,不计入答案。
调整花费的总次数:
在这里插入图片描述
【2】如果 n - i + 1 >= k,则扣掉最后 i - k 次调整。也就是说等效于从 an 开始不断减小当前最大的数到 ai,减小到出现 k 个 ai 时就停止。
调整花费的总次数:
在这里插入图片描述
③将 a1 调整为 ai,将 an 调整为 ai,将 a2 调整为 ai,将 an-1 调整为 ai,……。
于是最后共有 n 个 ai。因为总有 n >= k,所以只需扣除最后 n - k 次调整。
调整花费的总次数:
在这里插入图片描述

三、AC 代码

#include<cstdio>
#include<algorithm>
#pragma warning(disable:4996)
using namespace std;
const unsigned long long nmax = 200002;
unsigned long long n, k, a[nmax], s[nmax], t[nmax], c[nmax], r = UINT64_MAX, A, B; 
int main() {
	scanf("%llu%llu", &n, &k); for (unsigned long long i = 1; i <= n; ++i)scanf("%llu", a + i);
	sort(a + 1, a + n + 1);
	for (unsigned long long i = 1; i <= n; ++i)s[i] = s[i - 1] + a[i];
	for (unsigned long long i = n; i >= 1; --i)t[i] = t[i + 1] + a[i];
	for (unsigned long long i = 1; i <= n; ++i) {
		if (a[i] == a[i - 1])c[i] = c[i - 1] + 1;
		else c[i] = 1;
		if (c[i] >= k) { puts("0"); return 0; }
	}
	for (unsigned long long i = 1; i <= n; ++i) {
		A = i * a[i] - s[i] - (i - k); B = t[i] - (n - i + 1) * a[i] - (n - i + 1 - k);
		if (i >= k) { r = min(r, A); }
		if (n - i + 1 >= k) { r = min(r, B); }
		r = min(r, A + B - k + 1);
	}
	printf("%llu\n", r);
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值