zoukankan      html  css  js  c++  java
  • [Luogu 2090]数字对

    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 }
  • 相关阅读:
    大富翁8分析
    DCOM实现分布式应用(三)
    DCOM实现分布式应用(一)
    [转]职业生涯中的10个致命错误
    VC中展开宏
    zoj 2853 Evolution
    poj 1088 滑雪
    hdu 2437 Jerboas
    poj 3070 Fibonacci
    zoj 2976 Light Bulbs
  • 原文地址:https://www.cnblogs.com/NaVi-Awson/p/7448204.html
Copyright © 2011-2022 走看看