题目 2682:
蓝桥杯2022年第十三届省赛真题-GCD
时间限制: 3s 内存限制: 576MB 提交: 2999 解决: 800
题目描述
给定两个不同的正整数 a, b,求一个正整数 k 使得 gcd(a + k, b + k) 尽可能大,其中 gcd(a, b) 表示 a 和 b 的最大公约数,如果存在多个 k,请输出所有满足条件的 k 中最小的那个。
输入格式
输入一行包含两个正整数 a, b,用一个空格分隔。
输出格式
输出一行包含一个正整数 k。
样例输入
复制
5 7
样例输出
复制
1
提示
对于 20% 的评测用例,a < b ≤ 105 ;
对于 40% 的评测用例,a < b ≤ 109 ;
对于所有评测用例,1 ≤ a < b ≤ 1018 。
解题思路
gcd性质中,根据更相减损术可以知道一个等式:gcd(a,b)=gcd(a,b-a) 当然这里的前提时a<=b;所以gcd(a+k,b+k)=gcd(a+k,b-a) 这里的a和b都是已知的。我们可以设c=b-a 即c是已知的 所以想要使得a+k与c的最大公因子尽可能地大。因为最大最大能到达c 。显然这个式子的最大gcd一定为 c ,我们只需要计算出a 最少需要增加多少可以成为 c 的倍数,这个增量即是答案k。
例如:
a=5,b=7;求出c=7-5=2;d=a/c=5/2=1;如果a,c还差几个数成为倍数,需要再进行求余数a%c - d++;最后求出其相差多少个数d*c-a;
实现代码
#include<iostream>
using namespace std;
int main()
{
long long a,b,c,d;
cin>>a>>b;
if(a>b){
long long t=a;
a=b;
b=t;
}
c=b-a;
d=a/c;
if(a%c)
d++;
cout<<d*c-a<<endl;
return 0;
}