扩欧
首先,所謂歐幾里得定理,就是輾轉(zhuǎn)相除法。
代碼:
#include<bits/stdc++.h>int a,b;int gcd(int x,int y) {if (y==0) return x;//別記反了! return gcd(y,x%y); }int main(){scanf("%d%d",&a,&b);printf("%d\n",gcd(a,b));return 0; }這是遞歸的。
#include<bits/stdc++.h>int a,b;int gcd(int x,int y) {int r;while (y) {r=x%y;x=y; y=r;}return x; }int main(){scanf("%d%d",&a,&b);printf("%d\n",gcd(a,b));return 0; }這是非遞歸的。
然后我們可以用一種類似的方法解形如的不定方程,這就是擴(kuò)歐了。
其實(shí)有一個(gè)問題,這個(gè)方程為什么有解呢?
這涉及到一個(gè)叫貝祖定理的東西,我們先不管它,假設(shè)一定有解。。。
那么,這個(gè)方程咋解呢?
要用到一種利用歐幾里得定理的迭代的方法,大概是這樣滴:
先列出兩個(gè)形式與原方程一樣的式子,
很顯然,(都是求a和b的最大公約數(shù))
于是乎:
我們知道:(整個(gè)數(shù)減去可以被整除的部分)
所以:
再把右邊搞成a*...+b*...的形式:
瞧,現(xiàn)在兩邊形式一樣了。
因?yàn)槲覀冎灰唤M符合條件的解,所以只要讓并且就可以了。
那怎么求呢,顯然可以繼續(xù)遞歸下去。
不難發(fā)現(xiàn),a和b的值是一直在減小的(和輾轉(zhuǎn)相除法一樣,),邊界條件也和輾轉(zhuǎn)相除法一樣,即。
那么當(dāng)時(shí)會(huì)發(fā)生什么呢?(假如已經(jīng)遞歸了n次)
顯然,此時(shí)可取任何整數(shù),不妨設(shè)為0(寫123456也沒事)。
然后就可以遞歸回去了,最后得到的一組解。
大功告成!
代碼:
#include<bits/stdc++.h>int a,b; int x,y;void ex_gcd(int a,int b) {if (b==0) {x=1;y=0;//隨便寫其他整數(shù)值也可以 return ;//別忘返回了,不然進(jìn)死循環(huán)爆系統(tǒng)棧 }ex_gcd(b,a%b);int tmp=x; x=y;y=tmp-a/b*y; }int main(){scanf("%d%d",&a,&b);ex_gcd(a,b);printf("%d %d\n",x,y);return 0; }解同余方程時(shí)是一樣的(把模數(shù)看成b,給等式右邊減去y個(gè)b),只不過要輸出x的最小正整數(shù)解【洛谷P1082 同余方程】:
(wait!問題轉(zhuǎn)化看這里)
#include<bits/stdc++.h>int a,b; int x,y;void ex_gcd(int a,int b) {if (b==0) {x=1;y=0; return ;}ex_gcd(b,a%b);int tmp;tmp=x;x=y;y=tmp-a/b*y; }int main(){scanf("%d%d",&a,&b);ex_gcd(a,b);while (x<0) x+=b;printf("%d\n",x%b);return 0; }?
總結(jié)
- 上一篇: 加油站都需要什么手续_开办加油站需要办哪
- 下一篇: M11蓝牙音箱开不了机 解决方法