一道GCD问题
给定一个数组。现在让每个数都加上同一个非负整数k ,使得所有数的gcd(最大公约数)尽可能大。
求这个gcd最大值以及k的值。如果有多个k能得到这个最大的gcd,那么输出k的最小值。
保证数组长度不小于2,且至少有两个不相同的数!
输入描述:
第一行一个正整数 n (2≤n≤100000)
第二行n个正整数ai (1≤ai≤10^9)
输出描述:
一行两个数,分别代表最终gcd的最大值、以及达到这个最大值的最小的k 。
示例1:
输入:
2
1 3
输出:
2 1
k=1的时候,每个数加一,数组变成{2,4},最大公约数为2
示例2:
输入:
3
4 6 9
输出:
1 0
可以证明,无论k取什么值,最终的gcd都是1。所以k取最小值0。
代码如下:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll a[100005];//a数组用来存输入的数
int main()
{
int n;
cin>>n;
for(int i=0;i<n;i++)//输入
{
cin>>a[i];
}
sort(a,a+n);//排序
ll gcd=0;
for(int i=1;i<n;i++)
{
gcd=__gcd(gcd,a[i]-a[i-1]);//调用__gcd函数
}
printf("%d %d",gcd,(gcd-a[0]%gcd)%gcd);
return 0;
}
总结
多个数的更相减损术公式
gcd(x,y,z)=gcd(x,y-x,z-y)
在本题中,具体应用为gcd(a1+k,a2+k,a3+k,an+k)=gcd(a1+k,a2-a1,a3-a2,)
- __gcd是C++的求最大公因数的函数,对于__gcd(0,6),返回值是6。