zoj 3593 One Person Game
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 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或c步,c=a+b;问最小步数;
根据公式ax+by=c;,当x,y同号时等于max(x,y),当a,b异号时等于(abs(x)+abs(y)),因为a,b大于0,所以不管x,y同号还是异号都是当x,y,最接近时,答案最小
注意:取初值最大的时候直接赋值max=0x3f3f3f3f会WA,因为有的数据比它还大------------巨坑
#include<iostream> #include<string.h> #include<math.h> #define mx 0x3f3f3f3f #define ll long long #define mod 1000000007 using namespace std; ll x,y,r,s; void exgcd(ll a, ll b, ll &x, ll &y) //拓展欧几里得算法 { if(!b) x = 1, y = 0; else { exgcd(b, a % b, y, x); y -= x * (a / b); } } ll gcd(ll a,ll b) { return b==0?a:gcd(b,a%b); } void BD(ll a,ll b,ll c,ll r) { exgcd(a,b,x,y); x=x*c/r;//得到原方程的解x和y y=y*c/r; } int main() { ll t, A, B, a, b; scanf("%lld", &t); while (t--) { scanf("%lld%lld%lld%lld", &A, &B, &a, &b); r=gcd(a,b); if((B-A)%r!=0) printf("-1\n"); else { BD(a,b,B-A,r); ll mid,temp,ans=9999999999,x1,y1; a=a/r; b=b/r; mid=(y-x)/(a+b);//取x,y两直线交点的坐标值 for(int i=mid-1;i<=mid+1;i++) { x1=x+b*i; y1=y-a*i; if(x1*y1>=0) { temp=max(abs(x1),abs(y1)); } else { temp=abs(x1-y1); } ans=min(ans,temp); } printf("%lld\n",ans); } } //system("pause"); return 0; }