One Person Game(扩展欧几里得)

Posted qq-1585047819

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了One Person Game(扩展欧几里得)相关的知识,希望对你有一定的参考价值。

One Person Game

Time Limit: 2 Seconds      Memory Limit: 65536 KB

There is an interesting and simple one person game. Suppose there is a number axis under your feet. You are at point A at first and your aim is point B. There are 6 kinds of operations you can perform in one step. That is to go left or right by a,b and c, here c always equals to a+b.

You must arrive B as soon as possible. Please calculate the minimum number of steps.

 

Input

There are multiple test cases. The first line of input is an integer T(0 < T ≤ 1000) indicates the number of test cases. Then T test cases follow. Each test case is represented by a line containing four integers 4 integers ABa and b, separated by spaces. (-231 ≤ AB < 231, 0 < ab < 231)

Output

For each test case, output the minimum number of steps. If it‘s impossible to reach point B, output "-1" instead.

Sample Input

 

2
0 1 1 2
0 1 2 4

 

Sample Output

 

1
-1

 

 


Author: CAO, Peng
Contest: The 12th Zhejiang University Programming Contest

技术图片
 1 #include <iostream>
 2 #include <cstring>
 3 #include <algorithm>
 4 using namespace std;
 5 
 6 typedef long long ll;
 7 ll t;
 8 ll d1,d2,d3,d4;
 9 ll X,Y,a,b,c;
10 ll GDC;
11 
12 ll gdc(ll x,ll y)
13     return y==0?x:gdc(y,x%y);
14 
15 
16 void extend_gdc(ll a,ll b,ll &X,ll &Y)
17     if(b==0)
18         X=1;
19         Y=0;
20         return;
21     
22     extend_gdc(b,a%b,X,Y);
23     ll temp=X;
24     X=Y;
25     Y=temp-a/b*Y;
26 
27 
28 int main()
29     ios::sync_with_stdio(false);
30     while(cin>>t)
31         while(t--)
32             cin>>d1>>d2>>d3>>d4;
33             a=d3,b=d4,c=d2-d1;
34             GDC=gdc(a,b);
35             if(c%GDC!=0)
36                 cout << "-1" << endl;
37                 continue;
38             
39             extend_gdc(a,b,X,Y);
40             X=X*c/GDC;
41             Y=Y*c/GDC;
42             a=a/GDC;
43             b=b/GDC;
44             ll mid=(Y-X)/(a+b);
45             ll res=0x3f3f3f3f3f3f3f3f;
46             for(int i=mid-1;i<=mid+1;i++)
47                 ll ans=0;
48                 ll ee=X+b*i;
49                 ll rr=Y-a*i;
50                 if(ee*rr>=0) ans+=max(abs(ee),abs(rr));   //同号取最大值
51                 else ans+=abs(ee)+abs(rr);   //异号模相加
52 //                cout << ans << endl;
53                 res=min(res,ans);
54             
55             cout << res << endl;
56         
57     
58     return 0;
59 
View Code

 

 

以上是关于One Person Game(扩展欧几里得)的主要内容,如果未能解决你的问题,请参考以下文章

扩展欧几里得算法AcWing877.扩展欧几里得算法——扩展欧几里得算法证明

利用扩展的欧几里得算法求逆元

扩展欧几里得算法求逆元算法结果是负数

欧几里得和扩展欧几里得

欧几里得及扩展欧几里得

欧几里得算法和扩展欧几里得算法