扩展欧几里德
扩展欧几里德算法
关于不定方程ax+by=c
扩展欧几里德算法其实就是用来求出一组关于ax+by=c的解,复杂度比较稳定,是建立在欧几里德算法上面进行计算的。
首先需要考虑一下这个不定方程是否有解判断的方法就是:对于一个方程ax+by=c来说,如果 c%GCD(a,b)!=0 那么这个方程就是无解的。其实扩展欧几里德算法解出来的就是丢番图方程的解(好像是丢番图方程)。
首先我们需要看一下这个不定方程是否有解,如果有解的话,就进行计算,很显然的,如果b=0的时候,那么ax=c,那么x一定等于c/a。此时x=c/a,y=0;
然后,然后我们可以列出来两个方程:
- a*x1+b*y1=GCD(a,b);
- b*x2+(a%b)*y2=GCD(b,a%b);
然后根据欧几里德算法:GCD(a,b)=GCD(b,a%b);
所以就可以得到:a*x1+b*y1=b*x2+a%b*y2;
然后解得: x1=y2 y1=x2-a/b*y2;
然后我们就可以利用GCD的迭代解出来不定方程ax+by=c的一组解!
注意这里是一组解!!!!!!
但是你需要求出来其他解(比如大于零的最小解)
你就需要明白一个定理,也就是如果(x,y)是不定方程的一组解,那么(x+b/a,y-a/b)
也同样是一组解,然后我们就可以愉快的寻找其他解了……
比如大于零的最小x的解:(x%(LCM/a)+LCM/a)%LCM/a;原理和上面的(x+b/a,y-a/b)是一样的。但是(LCM/a)是满足x为整数的最小值。
- 最后我们来看一道神奇的题目:
青蛙的约会
题目描述:
我们把这两只青蛙分别叫做青蛙A和青蛙B,并且规定纬度线上东经0度处为原点,由东往西为正方向,单位长度1米,这样我们就得到了一条首尾相接的数轴。设青蛙A的出发点坐标是x,青蛙B的出发点坐标是y。青蛙A一次能跳n米,青蛙B一次能跳m米,两只青蛙跳一次所花费的时间相同。纬度线总长L米。现在要你求出它们跳了几次以后才会碰面。
输入:
输入只包括一行5个整数x,y,m,n,L,其中x≠y < 2000000000,0 < m、n < 2000000000,0 < L < 2100000000。
输出:
在单独一行里输出碰面所需要的跳跃次数,如果永远不可能碰面则输出一行“Impossible”。
题解:
- 这个一看就是扩展欧几里德啊……我们可以这样变幻一下。
- 首先,我们可以轻松的设出来方程:设x为两只青蛙需要跳的次数,a为A青蛙的初始位置,b为B青蛙的初始位置,然后解方程:
- (n*x+a)%L=(m*x+b)%L
- nx%L+a%L=mx%L+b%L
- nx%L-mx%L=b%L-a%L
- (n-m)x%L=(b-a)%L
- 设c=(b-a)%L,d=n-m,则c,d为可计算常数;
- dx%L=c
- dx+Ly=c
这个式子里面的x就是要输出的k!!!
数论超级有意思的!然后就是在开始扩展欧几里德之前先判断一下是否有解,就是if(c%GCD)是否为零,如果是则有解,否则无解。也就是判断一下c是不是x和y的最大公约数的倍数。
最后输出的时候用上面的方法找出来要求的最小正整数解就行了!
代码:
1 |
|