大体题意:
给你n 个数,让你选出尽可能多的数来,使得gcd(x1,x2,x3,,,xn) != 1; 输出最大数量?
思路:
思路比较偏比较麻烦,参考一下把!
gcd不是1的话,说明它们有共同的质因子!
数据范围是 每个数都是10W以内! 素数也就1W个
因此我们可以给每一个数进行质因子分解。
给分解出来的质因子p 统计一下,vos[p]++,表示有一个数 是p这个素因子。
最后统计这1W个素数的最大值即可!
有两个小坑把,都是自己挖的:
这个题肯定会选一个的,因此,最小值是1,不是0,但是因为数据有1,如果不特判的话,最小值是0,因此 给答案ans初始化为1即可。
另一个这样做会超时,因为后台数据可能有 10W个超大素数(接近10W的素数),这样边枚举输入边枚举素数会超时,因此要在质因子分解中时刻判断是否是素数,是素数就不用筛了, 直接return了,这样能快了很多。
详细见代码:
#include <bits/stdc++.h>
#define fi first
#define se second
#define ps push_back
#define mr make_pair
using namespace std;
const int inf = 0x3f3f3f3f;
typedef long long ll;
typedef unsigned long long LLU;
const double eps = 1e-10;
const double pi = acos(-1.0);
const int maxn = 100000 + 10;
int a[maxn];
vector<int>pri;
int vis[maxn];
int vos[maxn];
void init(){
int len = sqrt(100001) + 1;
for (int i = 2; i <= len; ++i) if (!vis[i])
for (int j = i*i; j <= 100000; j += i) vis[j] = 1;
for (int i = 2; i <= 100000; i++) if (!vis[i])pri.push_back(i);
}
void solve(int x){
for (int i = 0; i < pri.size(); ++i){
int p = pri[i];
if (!vis[x] || x == 1) {
vos[x]++;
return;
}
if (x % p == 0){
while(x % p == 0){
x/=p;
}
vos[p]++;
}
}
}
int main(){
init();
int n;
scanf("%d",&n);
for (int i = 0; i < n; ++i){
int x;
scanf("%d",&x);
a[i] = x;
solve(x);
}
int ans = 0;
for (int i = 0; i < pri.size(); ++i){
int p = pri[i];
ans= max(ans,vos[p]);
}
if (!ans) ++ans;
printf("%d\n",ans);
return 0;
}