題目來源: SGU
基準時間限制:1 秒 空間限制:131072 KB 分值: 40 難度:4級算法題
收藏
關注
給出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
這道題挺有意思,暴力優化一下直接過,注意下細節。
題目意思很明確,求兩個數的最大公約數,用gcd 雙循環感覺O(n*n)會爆
那可以把每個數都分解成因素,用數組保存出現次數,如果數組出現次數2,就與答案比較
1:注意只要遍歷2到 sqrt(n)就好了,如果整除,那麼兩個因素都加1,注意平方數時別重複加了
2:優化:如果一個數是單數,那麼遍歷時自增應該爲2,這樣比較快。
代碼獻上:
#include<cstdio>
#include<mem.h>
#include<iostream>
#include<math.h>
using namespace std;
int a[1000001],n,num,pingfan,ans=1,i,j;
int main()
{
memset(a,0,sizeof(a));
scanf("%d",&n); //輸入n個數
while(n--)
{
scanf("%d",&num);
pingfan=sqrt(num); //遍歷終點
if(num%2==0) //雙數,則自增爲1
{
for(i=2;i<=pingfan;i++)
{
if(num%i==0)
{
a[i]++; //能增除,則是因子
if(a[i]==2&&i>ans) //判斷保存最大的ans
ans=i;
if(num/i!=i) //避免平方數導致的重複
{
a[num/i]++;
if(a[num/i]==2&&num/i>ans)
ans=num/i;
}
}
}
}
else
{
for(i=3;i<=pingfan;i+=2)
{
if(num%i==0)
{
a[i]++;
if(a[i]==2&&i>ans)
ans=i;
if(num/i!=i)
{
a[num/i]++;
if(a[num/i]==2&&num/i>ans)
ans=num/i;
}
}
}
}
a[num]++;
if(a[num]==2&&num>ans)
ans=num;
}
printf("%d",ans);
return 0;
}