• 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 integersABa 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点,一次可以走x 步,或者 y步,或者x+y步。共有6种走法,因为前进和后退都是可以的。
    现在告诉你A,B位置,x ,y值。求最小的步数。
    思路:首先转化为求方程 ax+by=c的形式,题意将转化为max(x,y);这样似乎的正确的,但是不够完整。
    因为这个是在x,y都是同向的前提,如果x,y不方向走,那么就应该是abc(x)+abc(y);
    根据扩展欧几里得可以求出x' y'的取值范围。都是一条直线,而且它们的斜率肯定是一正一负,当它们有交叉点的时候,就是最优的。但是可能是小数。
    在这个点的前后几个点进行讨论,找出最值就可以了。

    #include<iostream>
    #include<stdio.h>
    #include<cstring>
    #include<cstdlib>
    #include<math.h>
    using namespace std;
    typedef long long LL;
    
    
    LL Ex_GCD(LL a,LL b,LL &x,LL &y)
    {
        if(b==0)
        {
            x=1;
            y=0;
            return a;
        }
        LL g=Ex_GCD(b,a%b,x,y);
        LL hxl=x-(a/b)*y;
        x=y;
        y=hxl;
        return g;
    }
    LL get(LL a,LL b)
    {
        if(a*b<0)
        {
            return abs(a)+abs(b);
        }
        else return abs(a)>abs(b)? abs(a):abs(b);
    }
    int main()
    {
        int T;
        LL A,B,a,b,g,x,y,ans,cur,c;
        scanf("%d",&T);
        while(T--)
        {
            scanf("%lld%lld%lld%lld",&A,&B,&a,&b);
            g=Ex_GCD(a,b,x,y);
            c=A-B;
            if(c<0) c=-c;
            if(c%g!=0)
            {
                printf("-1
    ");
                continue;
            }
            a=a/g;
            b=b/g;
            x=x*(c/g);
            y=y*(c/g);
    
            double t = (y-x)*1.0/(a+b);
            LL  K = (LL)t;
    
            cur = get(x+b*K,y-a*K);
            ans=cur;
    
            K++;
            cur=get(x+b*K,y-a*K);
            ans=min(ans,cur);
    
            K++;
            cur=get(x+b*K,y-a*K);
            ans=min(ans,cur);
    
            K=K-3;
            cur=get(x+b*K,y-a*K);
            ans=min(ans,cur);
    
            K=K-1;
            cur=get(x+b*K,y-a*K);
            ans=min(ans,cur);
    
            printf("%lld
    ",ans);
    
        }
        return 0;
    }
  • 相关阅读:
    [stm32] Systick
    [stm32] GPIO及最小框架
    51单片机-PC数据传输 温度 距离 监控系统设计
    [游戏学习29] Win32 图像处理1
    [51单片机] 串口通讯 简单通信
    [汇编] 闰年计算
    Java常用工具类之ArrayUtil
    常用工具类系列之DateUtil
    SpringBoot 获取当前登录用户IP
    Spring data jpa Specification查询关于日期的范围搜索
  • 原文地址:https://www.cnblogs.com/tom987690183/p/3736363.html
Copyright © 2020-2023  润新知