• 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;
    }
  • 相关阅读:
    scoket --- 练习
    网络编程---scoket使用,七层协议,三次挥手建连接,四次挥手断连接
    类的总复习
    面向对象 --- 类的绑定方法,面向对象高阶
    组合,访问限制机制,抽象类 --- 练习
    面向对象 --- 类的组合,封装,多态
    类的继承 --- 练习
    面向对象 --- 类的继承
    基于面向对象设计一个游戏
    请求头类型content-type
  • 原文地址:https://www.cnblogs.com/-citywall123/p/10698205.html
Copyright © 2020-2023  润新知