NEERC 2017

E:Equal numbers

题目大意 :n个数,选择0-n个数乘任意的倍数,使得n个数中不同的数的个数最少。

题解:对于一个数只有两种操作。1. 把它变成所有数的倍数。 2. 把它变成原数列中存在的一个数。并且对于给定的操作数,只能选择一种操作进行多次操作。所以预处理每个数是否在原数列中存在它的倍数。然后每次比较这两个操作谁更优,就是答案。

#include 
#define rep(i,s,t) for (int i=s;i<=t;++i)
using namespace std;
const int maxn=1e6+10;
int vis[maxn],a[maxn],b[maxn],q[maxn],cnt1,cnt2,cnt,s1,s2;
int main(){
    int n; scanf("%d",&n);
    rep(i,1,n){
        int t; scanf("%d",&t);
        if (!vis[t]) q[++cnt]=t;
        vis[t]++;
    }
    rep(i,1,cnt){
        int k=q[i];
        a[++cnt1]=vis[k];
        for (int j=2*k;j<=maxn-10;j+=k){
            if (vis[j]){
                b[++cnt2]=vis[k];
                break;
            }
        }
    }
    sort(a+1,a+1+cnt1); sort(b+1,b+1+cnt2);
    int l=1,r=1;
    rep(i,0,n){
        for(;l<=cnt1;l++){
            if (s1+a[l]>i) break;
            s1+=a[l];
        }
        for(;r<=cnt2;r++){
            if (s2+b[r]>i) break;
            s2+=b[r];
        }
        //printf("%d %d\n",l,r);
        printf("%d%c",cnt+1-max(l-1,r),i==n?'\n':' ');
    }
    return 0;
}

你可能感兴趣的:(ACM)