题目
最大公约数
思路
题目看起来很吓人,但往往题目越是吓人,就说明题的技巧很强。
题目要求 g c d ( F n + 1 , F n ) gcd(F_{n+1},F_n) gcd(Fn+1,Fn),并且已经知道的是: F 1 = A , F 2 = B , F i = F i − 1 + F i − 2 ( i > 2 ) F_1=A,F_2=B,F_i=F_{i−1}+F_{i−2}(i>2) F1=A,F2=B,Fi=Fi−1+Fi−2(i>2)
不妨设 g = g c d ( F n + 1 , F n ) g = gcd(F_{n+1},F_n) g=gcd(Fn+1,Fn), F n + 1 = x × g , F n = y × g F_{n+1}=x\times g,F_n=y\times g Fn+1=x×g,Fn=y×g,显然 x > y x>y x>y,则有 F n + 1 − F n = ( x − y ) × g = F n − 1 F_{n+1}-F_n=(x-y)\times g = F_{n-1} Fn+1−Fn=(x−y)×g=Fn−1,可以知道的是, F n − 1 = ( x − y ) × g F_{n-1}=(x-y)\times g Fn−1=(x−y)×g 也是 g g g 的倍数,也就是说 g = g c d ( F n + 1 , F n ) = g c d ( F n , F n − 1 ) g = gcd(F_{n+1},F_n)=gcd(F_n,F_{n-1}) g=gcd(Fn+1,Fn)=gcd(Fn,Fn−1)
以此类推,可以得到以下结论:
g = g c d ( F n + 1 , F n ) = g c d ( B , A ) g = gcd(F_{n+1},F_n)=gcd(B,A) g=gcd(Fn+1,Fn)=gcd(B,A)
所以直接求 A , B A,B A,B 的最大公约数即可。
代码
#include <iostream>
using namespace std;
using ULL = unsigned long long;
ULL gcd(ULL a, ULL b) {
ULL t = 0;
while (b) {
t = a % b;
a = b;
b = t;
}
return a;
}
int main(void) {
ULL a = 0, b = 0;
// 忽略 N,因为没用,也没必要开一个字符串去存
cin >> a >> b;
cout << gcd(a, b) << endl;
return 0;
}