题目:给出N个正整数,找出N个数两两之间最大公约数的最大值。例如:N = 4,4个数为:9 15 25 16,两两之间最大公约数的最大值是15同25的最大公约数5。
思路:给你两个数,让你求公约数,我们都知道用辗转相除法。
辗转相除法: int cal(int a,int b)
{
return b?cal(b,a%b):a;
}
但是注意这题,求多个数,n个数两两进行比较,n!次,肯定会超时。但是n个数每个数都不超过1000000,所以不妨从最大值开始,找到第一个是两个数的公约数的数,就是最大公约数。判断的时候可以直接根据值q,判断a[q]上有几个数,然后判断a[2q],减少了循环。
这里一个重要的思想就是把值当作地址存入数组,然后根据值判断个数。很多算法里会体现这个。比如最长公共子序转最长上升子序,把一个字符的值当地址,把输入的顺序当作值。
#include<iostream>
#include<algorithm>
#include<stdio.h>
#include<string.h>
using namespace std;
#define maxn 1000000+5
int a[maxn];
int main()
{
int n,q,i,j,count;
while (~scanf("%d",&n))
{
memset(a, 0, sizeof(a));
int maxsum=0;
for (i = 0; i < n; i++)
{
scanf("%d", &q);
a[q]++;
maxsum = max(maxsum, q);//找到最大数
}
for (i =maxsum; i > 0; i--)
{
count = 0;
for (j =i; j <=maxsum; j+=i)//判断有几个数的因子是它
{
count += a[j];
if (count >= 2)
break;
}
if (count >= 2)
break;
}
cout << i << endl;
}
return 0;
}