题解:P11837 [USACO25FEB] Making Mexes B
chenqishuo · · 题解
思路
这道题他是求在对于
对于
那怎么办呢?我们可以定义一个 cnt++;。
接下来就是判断至少需要修改多少次。经过观察我们可以发现:
-
当
cnt 为0 时,说明i 之前没有不包含的最小非负整数。这时如果i 的数量为0 ,那么i 为不包含的最小非负整数,修改次数就为0 次。 -
当
cnt 为0 时,如果i 的数量不为0 ,意味这i 为包含的非负整数,要令不包含的最小非负整数为i ,就需要把所有的i 修改为不为i 的值,修改次数就为i 的个数。 -
当
cnt 不为0 时,说明i 之前有不包含的最小非负整数。就需要把这cnt 个数各用一个数代替,如果i 这个数的个数小于等于cnt 时,我们就可以用所有的i 和其他有多余的数进行修改,直到刚好将这cnt 个数都代替,修改次数就为cnt 。 -
当
cnt 不为0 时,且i 这个数的个数大于cnt 时,我们就可以用所有的i 进行修改,直到刚好将这cnt 个数都代替,剩余的部分全部修改不为i 数,修改次数为i 的个数。
剩下的就可以交给代码实现了。
代码
时间复杂度:O(n)
#include <iostream>
using namespace std;
const int N = 2e5 + 10;
int a[N];
int main()
{
int n;
cin >> n;
for(int i = 1;i <= n; ++ i)
{
int x;
cin >> x;
a[x] ++; //计算每个相同的数的数量
}
long long cnt = 0;
for(int i = 0;i <= n; ++ i)
{
if(cnt > a[i])
cout << cnt << endl;
else cout << a[i] << endl;
//------------------------------------------------
//计算i之前不包含的最小非负整数的个数
if(a[i] == 0)
cnt ++;
}
return 0;
}