正题
题目链接:
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)
证明:
所以
我们设 a′=b a ′ = b , b′=a−b b ′ = a − b
那么
没错,是不是有些眼熟。更相减损术的次数就是到达一个数对需要的最少次数。
我们就可以枚举一个 x x ,然后求数对的最小次数。
但是!
会超时。然后我们就可以用欧几里得算法
我们可以发现
(b,a−b)
(
b
,
a
−
b
)
进行
x
x
次就是。所以我们可以发现如果要从
(b,a−bx)
(
b
,
a
−
b
x
)
变到
(b,a%b)
(
b
,
a
%
b
)
,
x
x
需要等于,所以我们可以用一个
wgcd(x,y)
w
g
c
d
(
x
,
y
)
表示变到数对
(x,y)
(
x
,
y
)
需要的次数,当
b=1
b
=
1
时我们只可以将
1
1
不断累加到上面所以需要的次数就是
a−1
a
−
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);
}