zoj 3593 One Person Game

One Person Game

Time Limit: 2 Seconds      Memory Limit: 65536 KB

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 ABa and b, separated by spaces. (-231 ≤ AB < 231, 0 < ab < 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
");
        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
",ans);
        }
    }
    //system("pause");
    return 0;
}
原文地址:https://www.cnblogs.com/-citywall123/p/10698205.html