扩展欧几里得与二元不定方程

二元不定方程,就是形同ax+by=c的二元方程,

只不过有无数组解罢了。

还有原谅我蒟蒻,不会用字母的写法,只好直觉+小学数学写法了

我们可以使用辗转相除法来解决(过渡好生硬啊)

我们首先来看一组例子

为了方便理解,特将每个多项式系数都写了出来,同时并没有将符号带进括号

37x-107y=25

37x-(37*2+33)y=25
37(x-2y)-33y=25

(-33*-1+4)(x-2y)-33y=25
-33(-x+3y)+4(x-2y)=25

(4*-8-1)(-x+3y)+4(x-2y)=25
4(9x-26y)-1(-x+3y)=25 

(-1*4+0)(9x-26y)-(-x+3y)=25
-(-37x+107y)+0(9x-26y)=25

我们自下而上看
因为系数0的存在
那么9x-26y=0
我们又可以惊奇的发现
9x-26y正好在它上面式子中出现了。
考虑整体思想,将括号内的多项式(就是(x-+3y))(or单项式)看做一个整体,便可求得(-x+3y)的值(当做一次方程来做)
再如此处理,便可将x,y的一对特值找出来 

那怎么求出其他的特值捏?

对于一个减法,我们总可以用正号将一个减数变成加数

那么就变成了两个数和相等的情况(真啰嗦)

那么我们这一个整数d

ax+by=c=a(x+bd)+b(y+ad)=c

因为将括号开出来时就将bd 和 ad消去了,所以两数的和不会改变

所以(x+bd)与 (y-ad)也是一组特解

这样有条件枚举d便会找到想要的特解

在理解了如何利用辗转相除法来求解后,再来看程序实现

#include<iostream>
using namespace std;
void exgcd(long long a,long long b,long long &x,long long &y,long long r)
{
    if(b==0)//有了系数0,为什么0肯定在b上?请回看gcd
    {
        x=r/a; //最终结果有可能系数为非零整数
        y=0;//e.....
        return ;
    }
    exgcd(b,a%b,x,y,r);//辗转相除
    //因为这里是回溯,注意下面写下一层就是递归意义上的下一层。可能理解起来有些别扭,原谅我吧233.
    long long k=x;//暂时保留下一层的x,注意是自下而上计算的
    x=y;//可以参考例子,例子我觉得自己写的很公正(就是有些别扭)
    y=k-a/b*y;//k是下一层的x,下一层的x是这一层的x-这一层的x,y的系数的商*这一层的x+这一层的y(不乘任何数)(这里的y是变量,储存的是下一层的x),便得到了这一层的y。
    return ;
}
int main()
{
    long long a,b,l;//ab为xy的系数,l为化成ax+by=c后的c
    cin>>a>>b>>l;
    long long x,y;
    exgcd(a,b,x,y,l); //扩展欧几里得是特殊的二元不等式
    cout<<x<<" "<<y;
}

扩欧只需要将ax+by=c中的c变为1即可

原文地址:https://www.cnblogs.com/Lance1ot/p/8494383.html

时间: 2024-10-13 14:27:14

扩展欧几里得与二元不定方程的相关文章

poj1061青蛙的约会(扩展欧几里得)

题目链接: 啊哈哈,点我点我 这道题是扩展欧几里得问题...哎,数学太弱了,看了半天才看懂.... 如果要相遇的话,则(n-m)*T+p*c=x-y成立,那么进行代换得到a*x+b*y=c,那么就转换成小白上面讲的了,所以用扩展欧几里得算法求得一组解,那么最后得到解的通式为x=x0+k*b/gcd(a,b),那么直接另右式子等于0及可..还有就是没有解的情况就是c%gcd(a,b)不等于0,那么就没有整数解...那么这个问题就得到了解决.... 题目: 青蛙的约会 Time Limit: 100

UVALive 6428 A+B 【扩展欧几里得】

题目链接:https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=4439 题目大意:给出a,b,S三个数,每次可以选择从a的位置加到b上,也可以从b的位置加到a上,问a或者b的位置上能否达到S. 比如:给出a和b,可以得到的是 (a b) (a+b b) (a a+b) (a+2b b)   (a+b a+2*b)     (2a+

扩展欧几里得定理——POJ 1061

对应POJ 题目:点击打开链接 青蛙的约会 Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 94409   Accepted: 17470 Description 两只青蛙在网上相识了,它们聊得很开心,于是觉得很有必要见一面.它们很高兴地发现它们住在同一条纬度线上,于是它们约定各自朝西跳,直到碰面为止.可是它们出发之前忘记了一件很重要的事情,既没有问清楚对方的特征,也没有约定见面的具体位置.不过青蛙们都是很乐观的,它们觉得

双六---扩展欧几里得---挑战编程

感谢http://www.cnblogs.com/oscar-cnblogs/p/6428920.html 题目描述 :一个双六(类似大富翁的桌上游戏)上面有向前 向后无限延续的格子, 每个格子都写有整数.其中0号格子是起点,1号格子是终点.而骰子上只有a,b,-a,-b四个整数,所以根据a和b的值的不同,有可能无法到达终点掷出四个整数各多少次可以到达终点呢?如果解不唯一,输出任意一组即可.如果无解 输出-1 问题就是求 ax+by = c的通解 证明一: 一定存在 x, y 使得 ax+by

欧几里得和扩展欧几里得

别人总结的,很详细,http://www.cnblogs.com/frog112111/archive/2012/08/19/2646012.html 欧几里得算法,就是人们常说的辗转相除法,比较好理解,主要作用是求两个数最大公约数,最小公倍数也可方便的求出 1 int gcd(int a,int b) 2 { 3 return b==0?a:gcd(b,a%b); 4 } View Cod 扩展欧几里得就非常神奇了,主要作用是解不定方程, 即  a * x + b * y = c ,我们都知道

pku 1061 青蛙的约会 扩展欧几里得

青蛙的约会Time Limit: 1000MS Memory Limit: 10000KTotal Submissions: 120482 Accepted: 25449Description 两只青蛙在网上相识了,它们聊得很开心,于是觉得很有必要见一面.它们很高兴地发现它们住在同一条纬度线上,于是它们约定各自朝西跳,直到碰面为止.可是它们出发之前忘记了一件很重要的事情,既没有问清楚对方的特征,也没有约定见面的具体位置.不过青蛙们都是很乐观的,它们觉得只要一直朝着某个方向跳下去,总能碰到对方的.

数论杂谈——欧几里得算法及扩展欧几里得

数学是oi的重要基础,所以说数论在oi中占据了非常重要的地位,因此,学好数学,对于一个oier来说也是非常重要的. oi中的数学,其实也就和数竞并没有什么区别. 欧几里得法辗转相除法求最大公约数 我们可以证明gcd(a,b)=gcd(b,a%b),也就是我国古代数学智慧的结晶,更相损减术.并且一直递归下去,直到b的值为零,最大公约数值即为a.在这里就不给出详细证明了,大家可以代几个数据去验证它一下.谁叫我数学太菜. 代码如下 int GCD(int a,int b) { if(!b) { ret

UVa 11768 格点判定(扩展欧几里得求线段整点)

https://vjudge.net/problem/UVA-11768 题意: 给定两个点A(x1,y1)和B(x2,y2),均为0.1的整数倍.统计选段AB穿过多少个整点. 思路: 做了这道题之后对于扩展欧几里得有了全面的了解. 根据两点式公式求出直线 ,那么ax+by=c 中的a.b.c都可以确定下来了. 接下来首先去计算出一组解(x0,y0),因为根据这一组解,你可以写出它的任意解,其中,K取任何整数. 需要注意的是,这个 a' 和 b' 是很重要的,比如说 b' ,它代表的是x每隔 b

【扩展欧几里得】BZOJ1477-青蛙的约会

一直在WA,后来我发现我把东西看反了-- [题目大意] 给出一个长度为L的环状坐标轴,两个点开始时位于(X,0).(Y,0).每次两点分别往右边移动m和n,问能否相遇? [思路] 由题意,可得: X+mt=Y+nt(mod L) (X+mt)-(Y+nt)=L*k (n-m)t+L*k=X-Y. 可以用扩展欧几里得来做.具体来说,显然要满足n-m和L的最大公约数(记为d)要整除X-Y,否则无解.这个可以在扩展欧几里得中求出. 式子可以化简为:[(n-m)/d]*t+(L/d)*k=(X-Y)/d