题意:给你一个起点A和终点B,你可以一次向前行进或者向后行进a,b,(a + b)米,问你最少多少次能够到达终点。
思路:直接扩展欧几里得,然后求出来通解以后再去求出来最优的通解就可以了。
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <fstream>
#include <iostream>
#include <list>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <vector>
#define MAXN 20100
#define MAXE 5
#define INF 1000000000
#define MOD 9901
#define LL long long
#define pi acos(-1.0)
using namespace std;
void exgcd(LL a, LL b, LL &d, LL &x, LL &y) {
if (!b) {
d = a;
x = 1;
y = 0;
} else {
exgcd(b, a % b, d, y, x);
y -= x * (a / b);
}
}
vector<LL> vec;
int main() {
std::ios::sync_with_stdio(false);
int T;
cin >> T;
LL A, B, a, b;
for (int kase = 1; kase <= T; ++kase) {
vec.clear();
cin >> A >> B >> a >> b;
LL s = labs(A - B);
LL d, x, y;
exgcd(a, b, d, x, y);
if (s % d) {
cout << -1 << endl;
} else {
a /= d;
b /= d;
x = s / d * x;
y = s / d * y;
double t = 1.0 * (y - x) / (a + b);
vec.push_back((LL) t);
vec.push_back((LL) t + 1);
vec.push_back((LL) t + 2);
vec.push_back((LL) t - 2);
vec.push_back((LL) t - 1);
LL sum = (LL) 1e15;
for (int i = 0; i < vec.size(); ++i) {
LL x0 = x + b * vec[i];
LL y0 = y - a * vec[i];
if (labs(x0 + y0) == labs(x0) + labs(y0)) {
sum = min(sum, (LL) max(labs(x0), labs(y0)));
} else {
sum = min(sum, (LL) (labs(x0) + labs(y0)));
}
}
cout << sum << endl;
}
}
return 0;
}