这道题我看题意看半天,一看懂就很简单了。
题意:首先有n个数,K表示n个数中不同的个数(比如说3个数1 2 3则K=3,1 2 2则K=2)
这K个数需要k bits(k=log2K),存这些数要nk bits空间。
现在给你一个I byte大小的磁盘来装这n个数(其实就是8I bits大小)使得这些数在区间[ l , r ]上,小于l的数全改成l,大于r的数全改成l,最少要修改多少个数。
思路:其实他问你最少要修改多少个数,就是在问你最多多少个数不用修改。先将所有的数排序,然后用vector<pair<int,int>> b来记录数字为b[i].first的数有b[i].second个。然后再顺序统计I磁盘上区间[ l , r ]上不用修改的个数。
下面是AC代码?
#include <bits/stdc++.h>
using namespace std;
int main()
{
int n, I;
ios::sync_with_stdio(false); cin.tie(0);
cin >> n >> I;
I *= 8;//转化成bits
vector<int>a(n);
for (int i = 0; i < n; i++)
cin >> a[i];
sort(a.begin(), a.end());
vector<pair<int, int>> b;
b.push_back({ a[0],1 });
int K = 1;//统计K的数量
for (int i = 1; i < n; i++)
if (a[i] == a[i - 1])
b.back().second++;
else
{
K++;
b.push_back({ a[i],1 });
}
int k = log(K)/log(2);//计算需要的k bits
if (K > (1 << k)) k++;//如果log(K)是小数则要+1
if (k * n <= I)
{
cout << 0; return 0;
}
K = (1 << I / n);//统计最多能有多少个不同的数
int ans = n;
int maxr = b.size(), cnt = 0, num = 0;
for (int l = 0, r = 0; r < maxr; l++)
{
while (r < maxr && num < K)
{
num++;
cnt += b[r].second;
r++;
}
ans = min(ans, n - cnt);
cnt -= b[l].second;
num--;
}
cout << ans;
return 0;
}