AcWing 1764. 修塔游戏
原题链接
中等
作者:
我要出去乱说
,
2021-02-18 21:16:33
,
所有人可见
,
阅读 461
#include <iostream>
using namespace std;
const int N = 1e4 + 10;
int n, k;
int c[N], s[N]; //c[i]表示高度为i的塔的数量,s[i]表示高度在i以内所有塔的高度之和
int main()
{
scanf("%d%d", &n, &k);
int max_cnt = 0;
for (int i = 0; i < n; i ++ )
{
int h;
scanf("%d", &h);
c[h] ++ ; //记录高度为h的塔数量
max_cnt = max(max_cnt, c[h]); //记录高度相同之塔的最大数量
}
for (int i = 1; i <= 1e4; i ++ ) //求前缀和
s[i] = s[i - 1] + i * c[i]; //高度在i及以内的所有塔高度总和
if (max_cnt >= k) puts("0");
else
{
int res = 2e9; //遍历塔的高度
for (int i = 1, cnt = 0; i < 1e4; i ++ ) //cnt表示高度小于i的塔的数量
{
int left = cnt * i - s[i - 1]; //左边全变成高度是i所需要的的操作数
//right = 所有塔高度和 - 高度在i以内的塔的高度和 - (高度大于i的塔数量) * i
int right = s[10000] - s[i] - (n - cnt - c[i]) * i;
//最后left - (~~~)的意思是多出来的相同高度的塔不需要操作
if (cnt + c[i] >= k) res = min(res, left - (cnt + c[i] - k)); //左塔数量>=k
if (n - cnt >= k) res = min(res, right - (n - cnt - k)); //右塔数量>=k
res = min(res, left + right - (n - k)); //左边右边都有的情况
cnt += c[i]; //更新该高度内所有塔的数量
}
printf("%d\n", res);
}
return 0;
}