One Person Game ZOJ - 3593 (Extended Euclidean)

One Person Game

Question link: ZOJ - 3593
question 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;
}




Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325774821&siteId=291194637