zoj 3593 One Person Game
http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=4677
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 toa+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 A, B, a and b, separated by spaces. (-231 ≤ A, B < 231, 0 <a, b < 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
题目大意:一个人的起点是A,终点是B,他每走一步可以选择走a米,也可以走b米,还可以走a+b米,可以往左走也可以往右走,问从A走到B最少需要走几步
可以设走x步a米的,走y部b米的,得到式子:
ax + by = B - A;
通过扩展欧几里德可得x和y
x、y的解集:X = x + b/gcd(a,b) * t;
Y = y - a /gcd(a,b) * t;
可将X、Y的式子看做两个直线方程,她们一个斜率为正一个斜率为负,肯定会有交点t,交点t处X==Y,此时所走的步数最少,但步数一定为整数,如果t为小数,就不能取t,需要往t的左右两边找(t - 1, t + 1)这个范围内肯定存在一个整数t使得所走步数最少,根据t可求得X、Y
(1)X、Y同号时,即方向相同,可以走a+b来减少步数,取max(X,Y)(这里可以画X、Y的坐标图来帮助理解)
(2)X、Y异号时,即方向相反,步数绝对值相加,abs(X) + abs(Y)
#include<stdio.h> #include<math.h> #include<string.h> #include<stdlib.h> #include<algorithm> using namespace std; typedef long long ll; const ll INF = 0x3f3f3f3f; ll r; void gcd(ll a, ll b, ll &x, ll &y) { if(b == 0) { x = 1; y = 0; r = a; return ; } gcd(b, a % b, x, y); ll t = x; x = y; y = t - a / b * y; } ll solve(ll a, ll b, ll c) { ll x, y, m; gcd(a, b, x, y); if(c % r != 0) return -1; a /= r; b /= r; x = c / r * x; y = c / r * y; ll ans = INF * INF; ll t = (y - x) / (a + b); for(ll i = t - 1 ; i <= t + 1 ; i++) { if(abs(x + b * i) + abs(y - a * i) == abs(x + b * i + y - a * i))//x、y同号 m = max(abs(x + b * i), abs(y - a * i)); else m = abs(x + b * i) + abs(y - a * i); ans = min(ans, m); } return ans; } int main() { int t; ll A, B, a, b, c; scanf("%d", &t); while(t--) { scanf("%lld%lld%lld%lld", &A, &B, &a, &b); c = B - A; ll ans = solve(a, b, c); printf("%lld\n", ans); } return 0; }