给出N个正整数,找出N个数两两之间最大公约数的最大值。例如:N = 4,4个数为:9 15 25 16,两两之间最大公约数的最大值是15同25的最大公约数5。
Input
第1行:一个数N,表示输入正整数的数量。(2 <= N <= 50000) 第2 - N + 1行:每行1个数,对应输入的正整数.(1 <= S[i] <= 1000000)
Output
输出两两之间最大公约数的最大值。
Input示例
4 9 15 25 16
Output示例
5
思路:
一,对于最大公约数一定在 1-Max(数组最大值)中,因此可以由大到小遍历GCD,对于 GCD只要查找它的倍数是否存在两个即可。
二,求出数组所有元素的全部约数,对于每个元素,可利用约数定理来求解。
Code 1 :
#include<iostream>
using namespace std;
const int MAX_S=1000005;
int n;
int a[MAX_S];
int main()
{
ios::sync_with_stdio(false);
cin>>n;
int Max=0;
for(int i=0,x;i<n;++i)
{
cin>>x;
Max=max(Max,x);
a[x]=1;
}
int ans=-1;
for(int i=Max;i>=0&&ans==-1;--i) //O(nlog(n))
for(int j=i,t=0;j<=Max;j+=i)
{
t+=a[j];
if(t>=2){
ans=i; break;
}
}
cout<<ans<<endl;
return 0;
}
Code 2 :
#include<iostream>
#include<cmath>
#include<map>
using namespace std;
const int MAX_S=1000005;
const int prime[205]={2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97,101,103,
107,109,113,127,131,137,139,149,151,157,163,167,173,179,181,191,193,197,199,211,223,227,229,233,239,241,
251,257,263,269,271,277,281,283,293,307,311,313,317,331,337,347,349,353,359,367,373,379,383,389,397,401,
409,419,421,431,433,439,443,449,457,461,463,467,479,487,491,499,503,509,521,523,541,547,557,563,569,571,
577,587,593,599,601,607,613,617,619,631,641,643,647,653,659,661,673,677,683,691,701,709,719,727,733,739,
743,751,757,761,769,773,787,797,809,811,821,823,827,829,839,853,857,859,863,877,881,883,887,907,911,919,
929,937,941,947,953,967,971,977,983,991,997,}; //168
int n;
int d[MAX_S];
map<int,int> imap;
void f(map<int,int>::iterator t,int p);
int main()
{
ios::sync_with_stdio(false);
cin>>n;
int Max=0;
for(int i=0,x;i<n;++i)
{
cin>>x;
Max=max(Max,x);
// for(int j=sqrt(x);j<=x;++j) //TEL
// if(x%j==0){
// d[x/j]++; d[j]++;
// }
imap.clear();
for(int i=0;i<168;++i)
{
while(x%prime[i]==0){
x/=prime[i];
imap[prime[i]]++;
}
if(x<prime[i]) break;
}
if(x!=1) imap[x]++;
f(imap.begin(),1);
}
int ans=0;
for(int i=Max;i>=0;--i)
if(d[i]>=2){
ans=i; break;
}
cout<<ans<<endl;
return 0;
}
void f(map<int,int>::iterator t,int p)
{
if(t==imap.end()){
d[p]++; return;
}
int aa=t->first,bb=t->second;
map<int,int>::iterator ti=t;
++ti;
for(int i=0,pi=1;i<=bb;pi*=aa,++i)
f(ti,p*pi);
}