Min Chain | ||
| ||
description | ||
Raven likes games of numbers. Today he meets two numbers and thinks whether he could get a result of 1 by doing at least one operation (addition or subtraction). However, he is tired of calculation; he also wants to know the minimum steps of operation that he could get 1.
| ||
input | ||
The first line of the input contains an integer T, which indicates the number of test cases.
In the following T rows, there are two positive integers a, b ( 0<=a, b<=10^9) in each row.
| ||
output | ||
For each case, output the least number of steps.
If you cannot get 1, just output -1.
| ||
sample_input | ||
Sample Input
3
3 2
16 9
6 8
| ||
sample_output | ||
1
10
-1
| ||
hint | ||
Sample 1: 3 - 2 = 1, One subtraction will be needed.
Sample 2: 16-9+16-9+16-9-9-9+16-9-9=1,It requires 10 additions and subtractions.
Sample 3: You cannot get 1. |
题意:给你两个数,求其最少经过多少次加减运算才能得到1.
经典扩展欧几里得算法
#include<iostream>
#include<cstring>
#include<cmath>
#include<cstdio>
#include<stack>
#include<algorithm>
using namespace std;
long long a,b;
long long exgcd(long long m,long long &x,long long n,long long &y)
{
long long x1,y1,x0,y0;
x0=1;y0=0;
x1=0;y1=1;
long long r=(m%n+n)%n;
long long q=(m-r)/n;
x=0;y=1;
while(r)
{
x=x0-q*x1;y=y0-q*y1;x0=x1;y0=y1;
x1=x;
y1=y;
m=n; n=r;r=m%n;
q=(m-r)/n;
}
return n;
}
int main()
{
int t;
long long x,y;
cin>>t;
while(t--)
{
scanf("%d%d",&a,&b);
if(b>a)
swap(a,b);
if(b==0)
{
if(a==1)
printf("1\n");
else
printf("-1\n");
}
else
if(b==1&&a==2)
printf("1\n");
else
if(b==1)
printf("2\n");
else
{
long long d=exgcd(a,x,b,y);
//cout<<x<<"&&"<<y<<endl;
if(d!=1)
printf("-1\n");
else
{
long long c=1,e;
e=x*c/b;
x=c*x-e*b;
y=(1-a*x)/b;
long long ans=fabs(x)+fabs(y);
printf("%lld\n",ans-1);
}
}
}
return 0;
}