One Person Game(zoj3593+扩展欧几里德)

One Person Game

Time Limit:2000MS     Memory Limit:65536KB     64bit IO Format:%lld
& %llu

Submit Status Practice ZOJ
3593

Appoint description: 
System Crawler  (2015-04-29)

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 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或者c的距离,其中c=a+b,问能不能走到B,能的话最少走几次。

思路:c = a+b, C = A-B,则等价于求{|x|+|y| | ax+by=C || ax+cy=C || bx+cy=C}。对于ax+by=C,

用扩展欧几里得算法求得ax+by=gcd(a,b),是否有解可由C是否为gcd的倍数判断。

若有解,原方程的一组解为(x0, y0)  = (xx*C/gcd, yy*C/gcd)。

令am=a/gcd,bm=b/gcd,则通解可表示为(x0+k*bm, y0-k*am)。

能使|x|+|y|最小的整点一定是最靠近直线与坐标轴交点的地方,

可以由|x|+|y|=C的图像不断平移看出。

由于负数取整时是先对它的绝对值取整,再添上负号,

所以考虑的范围要是[-x0/bm-1, -x0/bm+1] 、[y0/am-1, y0/am+1]。

转载请注明出处:http://blog.csdn.net/u010579068/article/details/45487153

#include<stdio.h>
#include<math.h>
#include<algorithm>
#define LL long long
using namespace std;

LL ans;
void exgcd(LL a,LL b,LL& d,LL& x,LL& y)
{
    if(!b){d=a;x=1;y=0;}
    else
    {
        exgcd(b,a%b,d,y,x);
        y-=x*(a/b);
    }
}
LL China(LL a,LL b,LL c)
{
    LL x,y,d,bm,am;

    exgcd(a,b,d,x,y);
    if(c%d) return -1;
    bm=b/d;
    am=a/d;
    x=x*c/d;
    y=y*c/d;

 //   printf("x=%lld,y=%lld\n",x,y);
    LL sum=fabs(x)+fabs(y);

    for(int i=-x/bm-1;i<=-x/bm+1;i++)
    {
        LL X=x+bm*i;
        LL Y=y-am*i;
        if(i)
        {
            LL tmp=fabs(X)+fabs(Y);
            if(tmp<sum) sum=tmp;
        }
    }
    for(int i=y/am-1;i<=y/am+1;i++)
    {
        LL X=x+bm*i;
        LL Y=y-am*i;
        if(i)
        {
            LL tmp=fabs(X)+fabs(Y);
            if(tmp<sum) sum=tmp;
        }
    }
    return sum;
}

int main()
{
    int T;
    LL A,B,C,a,b,c,d,x,y;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%lld%lld%lld%lld",&A,&B,&a,&b);
        c=a+b;
        C=fabs(A-B);
 //       ans==1<<30;
        LL t1=China(a,b,C);
        LL t2=China(a,c,C);
        LL t3=China(b,c,C);

        if(t1==-1&&t2==-1&&t3==-1)
        {
            printf("-1\n");
            continue;
        }
        if(t1>t2) ans=t2;
        else ans=t1;

        if(ans>t3) ans=t3;

        printf("%lld\n",ans);
    }
    return 0;
}
时间: 2024-10-19 09:22:17

One Person Game(zoj3593+扩展欧几里德)的相关文章

扩展欧几里德算法

文章来源:http://blog.csdn.net/zhjchengfeng5/article/details/7786595 谁是欧几里德?自己百度去 先介绍什么叫做欧几里德算法 有两个数 a b,现在,我们要求 a b 的最大公约数,怎么求?枚举他们的因子?不现实,当 a b 很大的时候,枚举显得那么的na?ve ,那怎么做? 欧几里德有个十分又用的定理: gcd(a, b) = gcd(b , a%b) ,这样,我们就可以在几乎是 log 的时间复杂度里求解出来 a 和 b 的最大公约数了

POJ2142 The Balance (扩展欧几里德)

本文为博主原创文章,欢迎转载,请注明出处 www.cnblogs.com/yangyaojia The Balance 题目大意  你有一个天平(天平左右两边都可以放砝码)与重量为a,b(1<=a,b<=10000)的两种砝码.让你求出一种方案称出重为c(1<=c<=50000)的物品,如有多种方案,请输出两种砝码需要数量的总和最小的方案. 输入 有若干行,每行三个数,a,b,c. 结束时用0 0 0表示. 输出 若干行,每行两个数,表示每个询问中a的数量与b的数量 如果无解输出 

欧几里德与扩展欧几里德算法(转)

欧几里德算法 欧几里德算法又称辗转相除法,用于计算两个整数a,b的最大公约数. 基本算法:设a=qb+r,其中a,b,q,r都是整数,则gcd(a,b)=gcd(b,r),即gcd(a,b)=gcd(b,a%b). 第一种证明: a可以表示成a = kb + r,则r = a mod b 假设d是a,b的一个公约数,则有 d|a, d|b,而r = a - kb,因此d|r 因此d是(b,a mod b)的公约数 假设d 是(b,a mod b)的公约数,则 d | b , d |r ,但是a

欧几理德,扩展欧几里德和模线性方程组。

欧几里德算法: 即求两个整数的最大公约数的一种快捷算法.也就是通常所说的“辗转相除法”.给定两个整数 a, b.欧几里德最坏可以在log(max(|a|, |b|))的复杂度内求出a, b的最大公约数.时间复杂度的计算方法也很有意思, 详见<算法导论>. 证明欧几里德算法的正确性: a可以表示成a = kb + r,且 r = a mod b 我们要证明欧几里德算法的正确性 也即是证明 gcd(a, b) = gcd(b, a%b=r) 假设d是a,b的一个公约数,则有 d|a, d|b,而r

HDU 1098 Ignatius&#39;s puzzle 费马小定理+扩展欧几里德算法

题目大意: 给定k,找到一个满足的a使任意的x都满足 f(x)=5*x^13+13*x^5+k*a*x 被65整除 推证: f(x) = (5*x^12 + 13 * x^4 + ak) * x 因为x可以任意取 那么不能总是满足 65|x 那么必须是 65 | (5*x^12 + 13 * x^4 + ak) 那么就是说 x^12 / 13 + x^4 / 5 + ak / 65 正好是一个整数 假设能找到满足的a , 那么将 ak / 65 分进x^12 / 13 + x^4 / 5中得到

POJ 2891-Strange Way to Express Integers(扩展欧几里德)

题目地址:POJ 2891 题意:给你k组同余关系,每组包含一个ai和ri,让你找出一个最小的数m,满足m%a1=r1,m%a2=r2.......m%ak=rk. 思路:纵观上述公式,很熟悉,其实就是求两两公式之间的最小值,例如K=3,那么先求第一组和第二组的最小,然后合并第一组和第二组,然后用合并之后的再和第三组找最小,最后的结果就是最终的结果.也就是这个题分两部分来完成. 1.找出两组最小.对于m%a1=r1和m%a2=r2可以得出两个公式m=a1*x+r1,m=a2*y+r2(x,y相当

HDU 2669 Romantic(扩展欧几里德)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2669 Problem Description The Sky is Sprite. The Birds is Fly in the Sky. The Wind is Wonderful. Blew Throw the Trees Trees are Shaking, Leaves are Falling. Lovers Walk passing, and so are You. ..........

POJ1061——青蛙的约会(扩展欧几里德)

青蛙的约会 Description两只青蛙在网上相识了,它们聊得很开心,于是觉得很有必要见一面.它们很高兴地发现它们住在同一条纬度线上,于是它们约定各自朝西跳,直到碰面为止.可是它们出发之前忘记了一件很重要的事情,既没有问清楚对方的特征,也没有约定见面的具体位置.不过青蛙们都是很乐观的,它们觉得只要一直朝着某个方向跳下去,总能碰到对方的.但是除非这两只青蛙在同一时间跳到同一点上,不然是永远都不可能碰面的.为了帮助这两只乐观的青蛙,你被要求写一个程序来判断这两只青蛙是否能够碰面,会在什么时候碰面.

HihoCoder - 1297 数论四&#183;扩展欧几里德

描述 小Hi和小Ho周末在公园溜达.公园有一堆围成环形的石板,小Hi和小Ho分别站在不同的石板上.已知石板总共有m块,编号为 0..m-1,小Hi一开始站在s1号石板上,小Ho一开始站在s2号石板上. 小Hi:小Ho,你说我们俩如果从现在开始按照固定的间隔数同时同向移动,我们会不会在某个时间点站在同一块石板上呢? 小Ho:我觉得可能吧,你每次移动v1块,我移动v2块,我们看能不能遇上好了. 小Hi:好啊,那我们试试呗. 一个小时过去了,然而小Hi和小Ho还是没有一次站在同一块石板上. 小Ho:不