Equal Numbers Gym
阿新 • • 發佈:2018-12-12
題目大意
給出n個數字,分別改變0~n個數字,使得數字種類數最少,每次列印數字種類數。
思路
讓種類數變小總共有兩種方法,一是n個數中一種數字是另一種的倍數,改變一種數就可以減少一種數,另一種是改變兩種數使得都變成這兩個數的公倍數。
可以先統計各種數的個數,然後從小到大排一下因為改變個數最少的數越容易減少種類數。
程式碼
#include <bits/stdc++.h>
using namespace std;
const int maxn = (int)1e6 + 10, inf = 0x3f3f3f3f;
int cnt[maxn];
int ct1[maxn], ct2[maxn] ;
int cur1, cur2;
int n;
void init() {
memset(cnt, 0, sizeof(cnt));
cur1 = cur2 = 0;
}
int main() {
// freopen("input.txt", "r", stdin);
freopen("equal.in", "r", stdin);
freopen("equal.out", "w", stdout);
init();
cin >> n;
for(int i = 0, t; i < n; i++) {
scanf ("%d", &t);
cnt[t]++;
}
for(int i = 0; i < maxn; i++) {
if(cnt[i]) {
ct1[cur1++] = cnt[i];
for(int j = 2*i; j < maxn; j+=i) {
if(cnt[j]) {
ct2[cur2++] = cnt[i];
break;
}
}
}
}
sort(ct1, ct1+cur1);
sort(ct2, ct2+cur2);
cout << cur1;
for(int p=0,q=0,sp=0,sq=0,i=1; i <= n; i++) {
while(p<cur1&&sp+ct1[p]<=i) {
sp+=ct1[p++];
}
while(q<cur2&&sq+ct2[q]<=i) {
sq+=ct2[q++];
}
cout << " " << cur1 - max(p-1, q);
}
cout << endl;
return 0;
}