codeforces Round 511 div.2 C

https://codeforces.com/contest/1047/problem/C

前天自己没写出来,直接干D题了,结果WA了两发才发现题目意思理解错了。。。。。。

参考别人写的题解后自己写的,尽力了。

//First we divide all numbers by GCD of them.
//Then we should find a subset with maximum number of integers GCD of which is bigger than 1.
//We can enumerate a prime p that GCD of the remaining integers can be divided by.
//And the number of integers can be divided by p is the maximum size of the subset.
//We can use Sieve of Euler to factor all integers in  time.
//Then we find the prime that can divide most integers.
//The answer is n minus the number of integers can be divided by this prime.
//If all integers are 1 (after dividing their GCD), there is no solution.
//先说题意,给你一堆数,设这些数的gcd为g,现在要把这些数的gcd这个值变大.
//首先我们把这些数的gcd求出来,因为a[i]的范围是1e5e7,所以标记一下a[i]/g的出现次数.
//然后遍历1.5e7,类似素数筛法,找出每一个的倍数出现了多少次(出现的次数越少,说明要删去的程度越低,
//一个数的倍数出现次数越多,说明同时拥有这个元素的数越多,删去),求个最大值,然后输出n-ans

#include<algorithm>
#include<cstdio>
#include<cstring>
using namespace std;

const int maxn = 3e5+7;
const int inf = 2e7+7;
int a[maxn];
int cnt[inf],vis[inf];

int main(){
    int n;
    while(scanf("%d",&n)==1){
        int g = 0;
        for(int i= 1;i<=n;i++){
            scanf("%d",&a[i]);
            g =__gcd(g,a[i]);    //求所有数的最大gcd
        }
        for(int i = 1; i<=n;i++){ 
           cnt[a[i]/g]++;
        }
        int Max = 0;
        for(int i = 2;i<inf;i++){ //共2到inf次寻找
            if(!vis[i]){          //比如如果2 的倍数出现的次数已经记录了,那么当i=4是,就不用记录了
                                  //因为标记的2的倍数出现的次数一定比4的倍数的数量多,就不用再记了
                int ans = 0;
                for(int j = i;j<= inf;j+=i){   //每次记录i的倍数出现的次数,2,4,6....为2的倍数,所以为j+=i;
                    vis[j] = 1;
                    ans = ans+cnt[j];
                }
                Max = max(Max,ans);
            }
        }
        if(Max)
            printf("%d\n",n-Max);
        else
            printf("-1\n");
    }
}

猜你喜欢

转载自www.cnblogs.com/tyhA-nobody/p/9693196.html