题目链接:http://codeforces.com/contest/1047/problem/C
题目大意:给你长度为n的数组,这个数组的gcd为m,输出能够使m变大的情况下至少要删除多少个数,如果删除数字不能使m变大的话,就为没有答案,输出-1
思路:把这些数除以他们所有数的最大公因数,保存在数组s1中,这s1中具有倍数(至少2倍)关系的数最多的个数即为保留的个数。
思考:为什么这样的复杂度没有被T?????
#include<bits/stdc++.h>
using namespace std;
const int N=1.5e7+5, M=3e5+5;
int a[M], s1[N], s2[N];
int main()
{
memset(s1, 0, sizeof(s1));
memset(s2, 0, sizeof(s2));
int n, g;
scanf("%d",&n);
for(int i=0;i<n;i++)
{
scanf("%d",&a[i]);
if(i==0)
g=a[0];
else
g=__gcd(g, a[i]);//所有数的最大gcd1
}
for(int i=0;i<n;i++)
{
s1[a[i]/g]++; //所有的数都除以g,统计个数
}
//max_s记录s1中有相同gcd2并且gcd>=2的数的最大个数
//即保留数字的最大个数,因为这些数的gcd3=gcd1*gcd2(gcd2>=2)
//所以gcd3>gcd1。保留最多则删除最少
int max_s=0;
for(int i=2;i<N;i++)
{
//统计具有相同公因数的数字个数
if(!s2[i])
{
int s=0;
for(int j=i;j<N;j+=i)
{
s+=s1[j];
s2[j]=1;//防止重复访问
}
max_s=max(max_s, s);
}
}
printf("%d\n",max_s?n-max_s:-1);
return 0;
}