歪解:
看到题目中的最小的最大,很容易想到二分,并且发现其满足单调性。时间复杂度 O ( n log n ) O(n\log n) O(nlogn),可以通过。
正解:
数学题,我们想到循环着摆放相同的数字是最优的。将所有出现次数最多的数字合在一起,作为循环节,然后在每两个循环节之间插入出现次数非最多的数字,其实就是插空。
假设出现次数最多的数字有 k k k 个,出现了 c n t cnt cnt 次,那么答案就是 ⌊ n − c n t × k k − 1 ⌋ + c n t + 1 \lfloor\dfrac{n - cnt\times k}{k - 1}\rfloor+cnt+1 ⌊k−1n−cnt×k⌋+cnt+1。时间复杂度 O ( n ) O(n) O(n),也是可以通过的。
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int maxn = 1e6 + 10;
int n, mx, cnt;
int c[maxn];
void solve()
{
cin >> n;
for (int i = 0; i <= n; ++i) c[i] = mx = cnt = 0;;
for (int i = 1, x; i <= n; ++i) cin >> x, c[x]++, mx = max(mx, c[x]);
for (int i = 1; i <= n; ++i) cnt += (c[i] == mx);
cout << cnt - 1 + (n - cnt * mx) / (mx - 1) << '\n';
}
signed main()
{
ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
int t;
cin >> t;
while (t--)
solve();
}