jzoj3793,P2090-数字对【更相减损术,欧几里得算法,数论】

正题

题目链接:
https://www.luogu.org/problemnew/show/P2090


大意

一个数对(a,b),每次可以变为(a+b,b)或(a,a+b)。然后要求一个数对中有n求从(1,1)变成这个数对的最小次数。


解题思路

更相减损法是gcd(a,b)=gcd(a,b-a)/gcd(a-b,b)
证明:

ad,bd a ∣ d , b ∣ d

所以
(ab)d ( a − b ) ∣ d

我们设 a=b a ′ = b b=ab b ′ = a − b
那么
gcd(a,b)=gcd(a,a+b) g c d ( a , b ) = g c d ( a , a + b )

没错,是不是有些眼熟。更相减损术的次数就是到达一个数对需要的最少次数。
我们就可以枚举一个 x x ,然后求数对(n,x)的最小次数。

但是!

会超时。然后我们就可以用欧几里得算法
我们可以发现 (b,ab) ( b , a − b ) 进行 x x 次就是(b,abx)。所以我们可以发现如果要从
(b,abx) ( b , a − b x ) 变到 (b,a%b) ( b , a % b ) x x 需要等于a/b,所以我们可以用一个 wgcd(x,y) w g c d ( x , y ) 表示变到数对 (x,y) ( x , y ) 需要的次数,当 b=1 b = 1 时我们只可以将 1 1 不断累加到a上面所以需要的次数就是 a1 a − 1
返回

wgcd(x,y)x1      (y=1)inf      (y=0)a/b+wgcd(y,x%y)      (y>1) w g c d ( x , y ) { x − 1             ( y = 1 ) i n f             ( y = 0 ) ⌊ a / b ⌋ + w g c d ( y , x % y )             ( y > 1 )


代码

#include<cstdio>
#include<algorithm>
using namespace std;
int n,mins;
int gcd(int x,int y)//wGCD
{
    if (y==1) return x-1;
    if (!y) return 1e9;
    return x/y+gcd(y,x%y);
}
int main()
{
    mins=2147483647;
    scanf("%d",&n);
    for (int i=1;i<=(n+1)/2;i++)//枚举(n,i)
        mins=min(mins,gcd(n,i));
    printf("%d",mins);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值