Description
对于一个数字对(a, b),我们可以通过一次操作将其变为新数字对(a+b, b)或(a, a+b)。
给定一正整数n,问最少需要多少次操作可将数字对(1, 1)变为一个数字对,该数字对至少有一个数字为n。
Input
第一行一个正整数 n
Output
一个整数表示答案。
Sample Input
5
Sample Output
3
Data Constraint
对于30%的数据, 1 <= n <= 1000
对于60%的数据, 1 <= n <= 20000
对于100%的数据,1 <= n <= 10^6
Hint
【样例解释】
(1,1) → (1,2) → (3,2) → (5,2)
题解:
本题是深度优先搜索
一开始是想着顺着题目思路的暴力,因为题目要求结果数字对至少有一个数字为n,所以可以表示为(n,x),对于给定的n,用i枚举所有的x,还原(n,i),取最小步数为解,变成(n-i,i),直到还原到(1,1)
但这个方法很容易会爆,所以我们思考有没有可以简化的方法。考虑到之前是减法,那么多次的减法就是除法了吧(^o^)/
若a>b,则(a,b)->(a mod b,b),步数+a/b;若b>a,同理可得(但在程序中,我们的设定是a严格大于b的,所以不需要用if来判断╮(╯▽╰)╭)(这样的算法gcd(辗转相除法)很像)
#include<cstdio>
#include<iostream>
#include<algorithm>
const int maxn=233333333;
const int N=1000010;
using namespace std;
int n,ans;
int qiu(int a,int b){
if (b==1) return a-1;
if (!b) return maxn;
return a/b+qiu(b,a%b); //加b步数+剩下步数
}
int main(){
scanf("%d",&n);
ans=maxn;
for (int i=1;i<n;i++) ans=min(ans,qiu(n,i));
printf("%d",ans);
return 0;
}