欧几里得

算法:理解“扩展欧几里得算法”

匿名 (未验证) 提交于 2019-12-02 23:48:02
这个算法还是有点意思的,需要一些思考量和理解。 欧几里得算法没扩展之前,计算的两个数的最大公约数,比如计算144和24的最大公约数,计算的过程如下: 最开始:144 24 第一次:24 144 % 24 即 24 0 发现直接整数了, 说明24就是144的公约数 ,所以计算结果就是:24 如果用a,b来表示,变为一般形式的话: 给定两个数(a, b),现在想计算两者的最大公约数,那么可以那b来模a, 如果结果为0,那说明b就是两者的最大公约数 ,如果有余数,比如: 最开始:14 6 第一次:6 14 % 6 即6 2 第二次:2 6 % 2 即2 0 反过来看:2是2、6的最大公约数,而6不是6、14的最大公约数,但是K * 6 + 2能够得到14,且6能被2整除,说明2是14的公约数。 如果将欧几里得算法进行扩展,就是这样,比如: 144 24,我们知道两者的最大公约数是24,那么144x + 24y = 24,这个x、y分别是什么呢?显然是x = 0,y = 1;但如果是14x + 6y = 2呢?通过上面求最大公约数的过程,我们能够知道,最后一步的2x1 + 6y1 = 2是很容易的得到结果的, 但是怎么样从这个结果推回来,得到一开始的y呢? ――这个就是扩展欧几里得算法。 这样来理解: 14x + 6y 6x2 + (14 % 6)y2 2x1 + (6 % 2)y1

扩展欧几里得算法

匿名 (未验证) 提交于 2019-12-02 23:45:01
所以,这个公式我们写作ax+by = d,(gcd(a, b) | d) 上面的思想是以递归定义的,因为 gcd 不断的递归求解一定会有个时候 b=0,所以递归可以结束。 这样我们就可以给出我们的代码了: void ex_gcd(int a, int b, int &x, int &y, int &d) { d = a; if (b == 0) { x = 1; y = 0; } else { ex_gcd(b, (a%b), y, x, d); y -= (a/b)*x; } } 上面的代码只是求出了方程 ax+by=gcd(a,b) 的解,但是对于解的形式没有限制 扩展:扩展欧几里得求解 ax + by = c 的最小正整数解(x,y) 当c%gcd != 0 则说明这个方程无解! 根据这个式子我们不难看出: 这里以求解最小正整数x为例: 于是我们就可以得到最小正整数的解 运用ex_gcd的时候,因为a,b,c可能为负值,即我们的t可能会为负数 这个时候我们就要让 同理如果求最小正整数的解y 就让t = a/gcd(a,b)   y = (y1 % t + t) % t #include<iostream> using namespace std; long long int exgcd(long long int a,long long int b,long long int

扩展欧几里得求逆元模板

匿名 (未验证) 提交于 2019-12-02 23:32:01
int exgcd ( int a , int b , int & x , int & y ) { int d = a ; if ( b != 0 ) { d = exgcd ( b , a % b , y , x ) ; y - = a / b * x ; } else { x = 1 ; y = 0 ; } return d ; } int inverse ( int a , int m ) { int x , y ; exgcd ( a , m , x , y ) ; return ( x % m + m ) % m ; } 文章来源: https://blog.csdn.net/w1304636468/article/details/90182303

python常用算法(6)——贪心算法,欧几里得算法

夙愿已清 提交于 2019-12-02 15:13:01
1,贪心算法   贪心算法(又称贪婪算法)是指,在对问题求解时,总是做出在当前看来是最好的选择。也就是说,不从整体最优上加以考虑,他所做出的的时在某种意义上的局部最优解。   贪心算法并不保证会得到最优解,但是在某些问题上贪心算法的解就是最优解。要会判断一个问题能否用贪心算法来计算。贪心算法和其他算法比较有明显的区别,动态规划每次都是综合所有问题的子问题的解得到当前的最优解(全局最优解),而不是贪心地选择;回溯法是尝试选择一条路,如果选择错了的话可以“反悔”,也就是回过头来重新选择其他的试试。 1.1 找零问题   假设商店老板需要找零 n 元钱,钱币的面额有100元,50元,20元,5元,1元,如何找零使得所需钱币的数量最少?(注意:没有10元的面额)   那要是找376元零钱呢? 100*3+50*1+20*1+5*1+1*1=375   代码如下: # t表示商店有的零钱的面额 t = [100, 50, 20, 5, 1] # n 表示n元钱 def change(t, n): m = [0 for _ in range(len(t))] for i, money in enumerate(t): m[i] = n // money # 除法向下取整 n = n % money # 除法取余 return m, n print(change(t, 376)) # ([3,

对拓展欧几里得算法的一点理解

筅森魡賤 提交于 2019-12-02 03:30:29
首先需要明确的一点是:这是一种算法,而非一个证明题。 算法的需求与数学证明题是不一样的,数学证明题要求严谨完整,而算法只需要证明我用到的某个的性质成立即可,相当于是“恰好发现了这一点”。 于是对于拓展欧几里得,我们是从欧几里得算法中发现了一个递推的性质,从而受到启发,产生猜想:可不可以利用递推求出二元一次方程的解? 我们把猜想建立在欧几里得算法之上,利用该算法的递推过程,贯穿该过程来得到想要解决问题的答案。 也就是说,我们仅仅需要证明我们得到的答案是正确的,而并非深刻挖掘欧几里得算法的过程。 拓展欧几里得算法及证明如下: ax+by=gcd(a,b) bx`+{a/b}by`=gcd(b,{a/b}b) 由于gcd(a,b)=gcd(b,{a/b}b), 得到ax+by=bx`+{a/b}by` ∵{a/b}=a/b-[a/b] ∴ax+by=bx`+(a/b-[a/b])by` ∴ax+by=bx`+(a-[a/b]b)y` ∴a(x-y`)=b(x`-y-[a/b]y`) 由于当x=y`,y=[a/b]y`-x`时该等式一定成立 //注意这里并不代表x=y`,y=[a/b]y`-x`是该等式的唯一解,而是我们取出了在实际情况中所需要的解 所以我们主观上取这一组解做我们的递归项 //因为这样可以解决我们的问题,可以求解方程 于是我们得到了这个递归公式

欧几里得,扩展欧几里得相关

余生颓废 提交于 2019-12-02 02:46:15
欧几里得(gcd) 欧几里得算法通过辗转相除法求得x,y的最小公约数 /* 迭代法(递推法):欧几里得算法,计算最大公约数 */ int gcd(int n, int m) { while(m>0)//余数大于零 { int c = n % m; n = m; m = c; } return n;//输出最后一个整除的数 } 扩展欧几里得 扩展欧几里得算法是欧几里得算法(又叫辗转相除法)的扩展。除了计算a、b两个整数的最大公约数,此算法还能找到整数x、y(其中一个很可能是负数)。通常谈到最大公因子时, 我们都会提到一个非常基本的事实: 给予二整数 a 与 b, 必存在有整数 x 与 y 使得ax + by = gcd(a,b)。有两个数a,b,对它们进行辗转相除法,可得它们的最大公约数–这是众所周知的。然后,收集辗转相除法中产生的式子,倒回去,可以得到ax+by=gcd(a,b)的整数解。 long long exgcd(long long a,long long b,long long &x,long long &y) { if (b==0) { x=1,y=0; return a; } long long d=exgcd(b,a%b,x,y); long long tmp=x; x=y; y=tmp-a/b*y; return d; } 通过扩展欧几里得求逆元 (A*X)

最大公约数

痞子三分冷 提交于 2019-12-02 00:22:16
一、辗转相除法   gcd(a,b)=gcd(b,a%b) 二、二进制算法优化   若x=y,则gcd(x,y)=x,否则:   ①若x,y均为偶数,则gcd(x,y)=2*gcd(x/2,y/2);   ②若x为奇数,y为偶数,则gcd(x,y)=2*gcd(x,y/2);   ③若x为偶数,y为奇数,则gcd(x,y)=2*gcd(x/2,y);   ④若x,y均为奇数,则gcd(x,y)=gcd(x-y,y);   代码实现 int gcd(int x,int y) { int i,j; if(x==0)return y; if(y==0)return x; for(i=0;!(x&1);i++)x>>=1; for(j=0;!(y&1);j++)y>>=1; if(j<i)i=j; while(1) { if(x<y)x^=y,y^=x,x^=y; x-=y; if(x==0)return y<<i; while(!(x&1))x>>=1; } } 三、最小公倍数   LCM(a,b)×GCD(a,b)=a×b 四、扩展欧几里得算法   首先我们有结论:ax+by=c的充分必要条件是gcd(a,b)|c   所以我们可以用扩展欧几里得定理来求解一组ax+by=gcd(a,b)的解   ∵gcd(a,b)=gcd(b,a%b)   ∴ax+by=gcd(a,b)=gcd(b

扩展欧几里得算法

半城伤御伤魂 提交于 2019-12-01 20:21:26
题目 给定两个整数 \(a,c,m\) 请求出模方程 \[ax\equiv c\mod m\tag{(1)}\] 的最小正整数解。 分析 我们构造方程 \[ax\equiv 1\mod m\tag{(2)}\] 不难发现,如果我们能求出 \((2)\) 中的一个解,将其乘上 \(c\) 即可得到 \((1)\) 的一个解。那么现在就要求 \((2)\) 的一个解。其等价于不定方程 \[ax+my=1\tag{(3)}\] 我们构造 \[mx+(a%b)y=1\tag{(4)}\] 来源: https://www.cnblogs.com/whx1003/p/11716609.html

扩展欧几里得--hdu1576

你。 提交于 2019-12-01 10:05:09
hdu-1576 Problem Description 要求(A/B)%9973,但由于A很大,我们只给出n(n=A%9973)(我们给定的A必能被B整除,且gcd(B,9973) = 1)。 Input 数据的第一行是一个T,表示有T组数据。 每组数据有两个数n(0 <= n < 9973)和B(1 <= B <= 10^9)。 Output 对应每组数据输出(A/B)%9973。 Sample Input 2 1000 53 87 123456789 Sample Output 7922 6060 扩展欧几里得模板 扩展欧几里得模板 由题意得 \[ ans=(\frac{A}{B})\%9973\\ n=A\%9973 \\ 得ans*B+9973*x = A = n+9973*y \\ \frac{ans}{n} *B+9973*(x*B-y) = n \\ 因gcd(B, 9973) = 1 \\ 即形如ax+by = gcd(a, b) \] #include <iostream> #include <algorithm> #include <string> #include <cstring> #include <cmath> #include <vector> #include <map> #include <set> #include <queue>

bzoj2187: fraction——类欧几里得

妖精的绣舞 提交于 2019-12-01 05:42:17
题意 多组询问,每次给出 $a, b, c, d$,求满足 $\frac{a}{b} < \frac{p}{q} < \frac{c}{d}$ 的所有二元组 $(p, q)$ 中 $p$ 为第一关键字,$q$ 为第二关键字排出来的字典序最小的那一对。 分析 设计函数 $f(a,b,p,q,c,d)$. 按照题目中保证 $q$ 最小的要求考虑该函数的几个边界: 1. $\left \lfloor \frac{a}{b} \right \rfloor-1 \leq \left \lceil \frac{c}{d} \right \rceil-1$,这个时候 $p = \left \lfloor \frac{a}{b} \right \rfloor+1, q=1$ 时字典序最小 2. $a=0$ 时,这个时候 $0 < \frac{p}{q} < \frac{c}{d} \Rightarrow q > \frac{dp}{c}$,显然 $p=1, q=\left \lfloor \frac{c}{d} \right \rfloor+1$ 时字典序最小 然后考虑辗转相除缩小问题规模: 1. $a > b\ or \ c > d$:原式等价于:$\frac{a\%b}{b} < \frac{p}{q}-\left \lfloor \frac{a}{b} \right \rfloor <