One Person Game
Question link: ZOJ - 3593question meaning: on a one-dimensional map, there are A, B, two points, each step can only take a or b or a+b units; ask at least a few steps to go from A to B, If it is not possible to go from A to B and output -1;
suppose that taking x steps a, y steps b can go from A to B, then there is a*x+b*y=BA; (The third move a+b is equivalent to A and b of the same number of steps are taken) If there is an integer solution to this equation, you can go from A to B, otherwise not; then, the next step is to find the minimum value of |x|+|y|;
determine whether the equation has The solution can be judged by extended Euclid, and the general solution can also be obtained;
if (BA)%gcd(a, b)==0, the equation has a solution, otherwise there is no solution;
according to extended Euclid, x can be obtained =x+bt, y=y-at; (t is an arbitrary integer);
emmmmm~ Mathematical knowledge is too lacking, when it reaches this point, it will not continue to count down, so I have to search for the solution;
|x|+|y| minimum value Near the intersection of the two straight lines x=x+bt and y=y-at;
#include <iostream> #include <algorithm> #include <string.h> #include <stdio.h> #include <math.h> using namespace std; const long long inf = 0x3f3f3f3f; long long exgcd(long long a, long long b, long long &x, long long &y){ if(b==0){ x=1; y=0; return a; } long long r=exgcd(b, a%b, x, y); long long t=x; x=y; y=ta/b*y; return r; } int main(){ int T; cin >> T; while(T--){ long long A, B, C; cin >> A >> B; long long a, b; cin >> a >> b; long long x, y; long long r; // Find the greatest common divisor of a, b; r=exgcd(a, b, x, y); C=B-A; //Determine whether there is a solution; if(C%r) cout << -1 << endl; else{ x*=C/r; y*=C/r; a/=r; b/=r; long long ans=inf*inf, tmp; long long mid=(yx)/(a+b);//mid is the intersection of two straight lines; for(long long T=mid-1; T<=mid+1; T++){ if((x+b*T)*(ya*T)>=0)//x, y has the same sign, it means to go in the same direction, take x steps a, y steps b, because you can also take a+b steps , so you can take max(x, y) steps; tmp=max(abs(x+b*T), abs(y-a*T)); else//x, y has an opposite sign, indicating that it is going in the opposite direction, taking x+y steps; tmp=abs(x-y+(a+b)*T); years=min(years, tmp); } cout << ans << endl; } } return 0; }