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"); } }