1 条题解
-
0
/* 可以发现题目中只关注一个数字的出现次数,而不关心这个数字的大小 所以我们可以将所有数字的出现次数进行统计,然后将所有数字的出现次数记录为 数组 这一步可以将 数组排序,也可以直接使用 进行统计 然后我们要做的事情就是保留下 数组中差值不超过 的一段,然后删去其他的部分即可 那么很容易想到我们可以将 数组进行排序,那么保留的一定是连续的一段,删除的就是头尾部分了,用一个前缀和就可以快速计算需要删除的数字数量了 那么关于枚举连续的一段,我们可以用双指针 进行枚举,也可以直接对于 二分查找一个第一个 但是这里要注意一个问题,那就是对于我们找出的数字区间 而言,我们需要进行的操作应该是将 的数字删光,对于 的数字并不需要全部删光,只要删到 即可,这是一个坑,要注意 那么对于一个区间 而言,最终保留的数字数量应该是 然后对 求最小值即可 */ #include<bits/stdc++.h>
using namespace std;
map<int, int> cnt;
int a[100010], n, m, x, len, ans = 1e9, s[100010]; int main() { freopen("put.in","r",stdin); freopen("put.out","w",stdout); scanf("%d%d", &n, &m); for (int i = 0; i < n; i++){ cin >> x; cnt[x]++; } for (map<int, int>::iterator i = cnt.begin(); i != cnt.end(); ++i){ a[++len] = i->second; } sort(a + 1, a + len + 1); for (int i = 1; i <= len; i++){ s[i] = s[i - 1] + a[i]; } for (int i = 1; i <= len; i++){ int j = upper_bound(a + i, a + len + 1, a[i] + m) - a - 1; int sum = s[j] - s[i - 1] + (len - j) * (a[i] + m); ans = min(ans, n - sum); } printf("%d\n", ans); return 0; }
- 1
信息
- ID
- 9995
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 8
- 标签
- 递交数
- 35
- 已通过
- 6
- 上传者