Description
对于一个数字对(a, b),我们可以通过一次操作将其变为新数字对(a+b, b)或(a, a+b)。
给定一正整数n,问最少需要多少次操作可将数字对(1, 1)变为一个数字对,该数字对至少有一个数字为n。
Input
第一行一个正整数 n
Output
一个整数表示答案。
Sample Input
5
Sample Output
3
Hint
样例解释:
(1,1) → (1,2) → (3,2) → (5,2)
对于30%的数据, 1 <= n <= 1000
对于60%的数据, 1 <= n <= 20000
对于100%的数据,1 <= n <= 10^6
题解
我们注意到对于数对$(x,y)$,$x>y$,一定是由$(x-y,y)$推得的,我们发现就是更相减损术。
我们可以枚举$<n$的所有数,做一遍$gcd$,统计操作次数。
最终,如果其中一个数为$1$,那么我们可以去更新一下答案;
但如果为$0$,即最初始数对不合法,舍去。
1 #include<set> 2 #include<map> 3 #include<cmath> 4 #include<ctime> 5 #include<queue> 6 #include<stack> 7 #include<vector> 8 #include<cstdio> 9 #include<string> 10 #include<cstdlib> 11 #include<cstring> 12 #include<iostream> 13 #include<algorithm> 14 using namespace std; 15 16 int n,cnt; 17 int gcd(int a,int b) 18 { 19 int cnt=0; 20 while (true) 21 { 22 if (b==0) return 0; 23 if (b==1) 24 { 25 cnt+=a-1; 26 break; 27 } 28 cnt+=a/b; 29 a%=b; 30 swap(a,b); 31 } 32 return cnt; 33 } 34 35 int main() 36 { 37 scanf("%d",&n); 38 int ans=~0u>>1; 39 if (n==1) printf("0 "); 40 else 41 for (int i=1;i<n;i++) 42 { 43 int cnt=gcd(n,i); 44 if (cnt) ans=min(ans,cnt); 45 } 46 printf("%d ",ans); 47 return 0; 48 }