我们首先要搞清楚的是,最大公约数是怎么算出来的。
a和b的最大公约数,其本质就是他们公因子中最大的那个,所以我们把问题指向了公因子的个数,所以首先就是分解这n个数的因子,最后利用出现次数的桶数组找到最优解。
这里需要注意一点,有些较大的因子可能出现的次数比较多,反而较小的因子可能出现的次数比较少,那么我们就需要逆向更新,因为n个数中出现n次的因子非常固定,一定是1,所以逆向更新,即得最优解
7-9 最大公约数2 (20分)
最大公约数2
从n个数中挑出k个数,使这k个数的最大公约数最大。
输入格式:
第一行一个正整数n(n≤10000)。 第二行为n个空格隔开的正整数,代表这n个数,其中max(ni)≤1000000。
输出格式:
总共n行,第i行为k=i情况下的最大公约数。
输入样例:
4
1 2 3 4
输出样例:
4
2
1
1
#include<iostream>
#include<cstdio>
#include<cmath>
using namespace std;
#define MAXN 1000015
int n,p[MAXN],c[MAXN];
void get(int x)
{
for(int i = 1; i <= sqrt(x); i++)
{
if(x%i) continue;
p[i]++;
if(i*i != x) p[x/i]++;
}
}
int main()
{
cin>>n;
int x;
for(int i = 0; i < n; i++) scanf("%d",&x),get(x);
for(int i = 1; i <= 1000000; i++) c[p[i]] = max(c[p[i]],i);
for(int i = n; i > 1; i--) if(c[i-1] == 0) c[i-1] = c[i];
for(int i = 1; i <= n; i++) printf("%d\n",c[i]);
return 0;
}