小G的GCD
题目链接:nowcoder 217463
到主站看:https://blog.csdn.net/weixin_43346722/article/details/116243756
题目大意
问你 gcd(x,y) 用辗转相除法来求,如果限定 x,y 都小于一个值,那辗转相除法的递归最多要递归多少次。
思路
这道题给出了暴力程序,那我们就试着运行一下它,用它看看有什么规律。
然后你就从 0 开始试,你会发现答案是这样子的:(从 0 开始)
0,2,3,4,5,5,6,6,6,7,7,7,7,7,……
然后你会发现,除了 0,其它还挺有规律的,进过了一定的个数就比原来多了个 1,而且这个个数还在增加。
然后你可以看看每次的个数是多少(不算 0 了):1,1,2,3,5,……
你会发现它很像斐波那契数列,然后试着跟着算一下,发现暴力答案跟你的答案一样。
那就可以开搞了。
(其实听说可以推理出来,但是我这种弱鸡肯定是不会的啦)
代码
#include<cstdio>
#include<iostream>
#define ll long long
using namespace std;
ll n, ans, a, b, c;
//根据题目给定代码进行打标找规律
//long long GCD(long long x, long long y) {
// if (!y) return 1ll;
// return GCD(y, x % y) + 1ll;
//}
//
//long long maxGCD(long long n) {
// long long ans = 0ll;
// for (long long i = 1; i <= n; i++)
// for (long long j = 1; j <= n; j++)
// ans = max(ans, GCD(i, j));
// return ans;
// }
int main() {
scanf("%lld", &n);
// printf("%lld", maxGCD(n));
if (n == 0) printf("0");//先搞前几位
if (n == 1) printf("2");
if (n == 2) printf("3");
if (n == 3) printf("4");
if (n > 3) {
n -= 3;
ans = 4;
a = 1;
b = 1;
c = 2;
while (c < n) {//根据打标找出的规律(斐波那契)来找答案
ans++;
n -= c;
a = b;
b = c;
c = a + b;
}
printf("%lld", ans + (c == n));
}
return 0;
}
//打标找规律的草稿
/*
1 2//奇数行表示第一次出现这个答案(第二个数)n 是多少(第一个数)
1//偶数行表示之间相差了多少个数
2 3
1
3 4
2
5 5
3
8 6
5
13 7
8
21 8
13
34 9
*/ 
京公网安备 11010502036488号