ZOJ One Person Game

目录

1.题目

2.中文翻译

3.思路解析:

4.代码实现:


1.题目

One Person Game

Description 

        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. ($-2^{31} ≤ A, B < 2^{31}, 0 < a, b < 2^{31}$)

Output
 For each test case, output the minimum number of steps. If it’s impossible to reach point B, output “-1” instead.

Examples
intput

2
0 1 1 2
0 1 2 4

output

1
-1

2.中文翻译

题目描述

        有一个有趣而简单的单人游戏。假设你脚下有一个数字轴。你一开始是在点 A ,你的目标是点  B  。一步可以执行6种操作。也就是向左或向右移动 a、b 和 c ,这里 c 总是等于 a+b 。

        你必须尽快到达B。请计算最小步数。

输入

        有多个测试用例。输入的第一行是一个整数 T(0<T≤1000) 表示测试用例的数量。然后是T行测试案例。每个测试用例由一行表示,该行包含四个整数4个整数 A、B、a 和 b,用空格分隔。(-2^{31}≤A,B<2^{31},0<A,B<2^{3})

输出

        对于每个测试用例,输出最小步骤数。如果无法到达B点,则输出“-1”。

样例输入

样例输出

3.思路解析:

        1.题目其实就是求 C1*a + C2*b + C3*c + C4*(-a)+C5*(-b)+C6*(-c)| = |A-B|,根据题意化简之后就变成了 |C1a+C_2b| = |A-B| ,目的就是判断左边这个方程是否有解.

        2.欧几里得扩展算法:我的算法专栏里面有讲解。

4.代码实现:

#include <algorithm>
#include <string.h>
#include <iostream>
#include <stdio.h>
#include <string>
#include <vector>
#include <queue>
#include <map>
#include <set>
using namespace std;
typedef long long LL;
const int N = 1e5+10;
 
LL exgcd(LL a,LL b,LL &x,LL &y)
{
    if(b==0)
    {
        x=1, y=0;
        return a;
    }
    LL ans=exgcd(b,a%b,x,y);
    LL tmp=x;
    x=y;
    y=tmp-a/b*y;
    return ans;
}
 
int main()
{
    int t;
    scanf("%d", &t);
    while(t--)
    {
        LL A, B, a, b, c, x, y;
        scanf("%lld %lld %lld %lld",&A, &B, &a, &b);
        if(A>B) swap(A,B);
        c=(B-A);
        LL g=exgcd(a,b, x, y);
        if(c%g!=0) puts("-1");
        else
        {
            a/=g, b/=g;
            x*=(c/g), y*=(c/g);
            LL k=(y-x)/(a+b);
            LL ans=10000000000ll;
            for(LL i=k-1;i<=k+1;i++)
            {
                if(abs(x+i*b)+abs(y-i*a)==abs(x+i*b+y-i*a)) ans=min(ans,max(abs(x+i*b),abs(y-i*a)));
                else   ans=min(ans,abs(x+i*b)+abs(y-i*a));
            }
            cout<<ans<<endl;
        }
    }
    return 0;
}

     

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值