• zoj 3593 One Person Game


    http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=4677

    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 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 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,他每走一步可以选择走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
    ", ans);
        }
        return 0;
    }
  • 相关阅读:
    Instant Python 中文缩减版
    《Java疯狂讲义》(第3版)学习笔记 2
    《Java疯狂讲义》(第3版)学习笔记 1
    NXP Mifare S50标准IC卡- 访问位(Access Bits) 分析
    Python中获取异常(Exception)信息
    支持向量机(SVM)入门
    棋类游戏中人机博弈的设计
    (翻译)如何对python dict 类型按键(keys)或值(values)排序
    Python实现打印二叉树某一层的所有节点
    FIFA halts 2026 bids amid scandal 国际足联在丑闻期间停止2026年足球世界杯申请
  • 原文地址:https://www.cnblogs.com/qq2424260747/p/4919649.html
Copyright © 2020-2023  润新知