首先要把欧几里得弄清楚,要不很难弄的·········
ax + by = c;
计算出的为 ax + by = gcd(a,b);
r = gcd(a,b)
所以要求真正的x,y则需要乘上 c/gcd(a,b);
然后x,y求的是其中一组解
它的一系列解为 X = x + bt;
Y = y - at;
a = a/r,b = b/r; 这样得出的x,y的解更多,更全面
然后··············
说题意吧···········
题意为可以走长度a,b,a+b 三种长度,求由A到B的最小步数
其实就是求ax + by = (B- A)因为(a + b)可以分解
所以就是找一组xy的值
当xy为同号时就是找x,y的最大值
当xy异号时即为|x| + |y|的值
那么最短路径就是x等于y的时候步数最少
在条线的交点附近
代码如下
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
typedef long long ll;
const ll inf = 0x3f3f3f3f;
ll exgcd(ll a,ll b,ll &x,ll &y)
{
if(b == 0)
{
x = 1;
y = 0;
return a;
}
ll r = exgcd(b,a%b,x,y);
ll t = x;
x = y;
y = t - a/b*y;
return r;
}
int main()
{
int t;
cin>>t;
while(t--)
{
ll A,B,C,a,b;
cin>>A>>B>>a>>b;
ll x,y;
ll r;
r = exgcd(a,b,x,y);
C = B - A;
if(C%r)
cout<<"-1"<<'\n';
else
{
x = x*(C/r);
y = y*(C/r);
a = a/r;
b = b/r;
ll ans = inf*inf,tmp;
ll mid = (y - x)/(a + b);//两条直线交点的x坐标
for(ll T = mid - 1; T <= (mid + 1); T++)
{
if((x + b*T)*(y - a*T) >=0)
{
tmp = max(abs(x + b*T),abs(y - a*T));
}
else
tmp = abs(x - y + (a + b)*T);
ans = min(ans,tmp);
}
cout<<ans<<'\n';
}
}
return 0;
}