擴充歐幾裡得,擴充歐幾裡德

來源:互聯網
上載者:User

擴充歐幾裡得,擴充歐幾裡德

歐幾裡德演算法又稱輾轉相除法,用於計算兩個整數a,b的最大公約數。

基本演算法:設a=qb+r,其中a,b,q,r都是整數,則gcd(a,b)=gcd(b,r),即gcd(a,b)=gcd(b,a%b)。

遞迴代碼:

__int64 gcd(__int64 a,__int64 b){    return b==0?a:gcd(b,a%b);}

擴充歐幾裡得

基本演算法:對於不完全為 0 的非負整數 a,b,gcd(a,b)表示 a,b 的最大公約數,

          必然存在整數對 x,y ,使得 gcd(a,b)=ax+by。

證明:設 a>b。

1,顯然當 b=0,gcd(a,b)=a。此時 x=1,y=0;

2,ab!=0 時,設 ax1+by1=gcd(a,b);

  bx2+(a mod b)y2=gcd(b,a mod b);

  根據樸素的歐幾裡德原理有 gcd(a,b)=gcd(b,a mod b);

  則:ax1+by1=bx2+(a mod b)y2;

  即:ax1+by1=bx2+(a-(a/b)*b)y2=ay2+bx2-(a/b)*by2;

  根據恒等定理得:x1=y2; y1=x2-(a/b)*y2;

   這樣我們就得到了求解 x1,y1 的方法:x1,y1 的值基於 x2,y2.

  上面的思想是以遞迴定義的,因為 gcd 不斷的遞迴求解一定會有個時候 b=0,所以遞迴可以結束。

遞迴代碼:

__int64 exgcd(__int64 a,__int64 b,__int64 &x1,__int64 &y1){    __int64 t,d;    if(b==0){        x1=1;        y1=0;        return a;    }    d=exgcd(b,a%b,x1,y1);    t=x1;    x1=y1;    y1=t-a/b*y1;    return d;}


擴充歐幾裡德演算法的應用主要有以下三方面:

(1)求解不定方程;

(2)求解模線性方程(線性同餘方程);

(3)求解模的逆元;

補充定理:

1.設a,b,c為任意整數。若方程ax+by=c的一組整數解為(x0,y0),則它的任意整數解都可以寫成(x0+kb',y0-ka'),其中a'=a/gcd(a,b),b'=b/gcd(a,b),k為任意整數
2.定理:若ax+by=g,(g=gcd(a,b),即g是a,b的最大公約數)有整數解;則ax+by=c(c是g的倍數)有整數解



擴充歐幾裡得演算法PASCAL

gcd(a,b)=ax+by
gcd(b,a mod b) = bx'+(a mod b) y'
=bx'+ ( a- (a div b) *b)y'
=bx'+ ay'- (a div b) *b *y'
=ay'+ b(x'- (a div b) y')
因為gcd(a,b)=gcd(b , a mod b)
所以ax+by=ay'+ b(x'- (a div b) y')
x=y'
y=x'- (a div b) y'

var
a,b,x,y,k:integer;

function extended_gcd(a,b:longint; var x,y:longint):longint;
var
t:longint;
begin
if b=0 then
begin
x:=1; y:=0;
exit(a);
end;
extended_gcd:=extended_gcd(b,a mod b , x, y);
t:=x;
x:=y;
y:=t - (a div b)*y;
end;

begin
readln(a,b);
k:=extended_gcd(a,b,x,y);
writeln(a,'*(',x,')+',b,'*(',y,')=',k);

readln;
end.

分給的也忒少了
 
擴充歐幾裡得演算法 好懂一點

歐幾裡德演算法又稱輾轉相除法,用於計算兩個整數a,b的最大公約數。其計算原理依賴於下面的定理:
定理:gcd(a,b) = gcd(b,a
mod 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 = kb +r
因此d也是(a,b)的公約數
因此(a,b)和(b,a mod
b)的公約數是一樣的,其最大公約數也必然相等,得證
歐幾裡德演算法就是根據這個原理來做的,其演算法用C++語言描述為:
int
Gcd(int a, int b)
{
if(b ==
0)
return a;
return
Gcd(b, a % b);
}
當然你也可以寫成迭代形式:
int
Gcd(int a, int b)
{
while(b !=
0)
{
int r = b;
b = a % b;
a =
r;
}
return
a;
}
本質上都是用的上面那個原理。
補充:
擴充歐幾裡德演算法是用來在已知a,
b求解一組x,y使得a*x+b*y=Gcd(a,b)(解一定存在,根據數論中的相關定理)。擴充歐幾裡德常用在求解模線性方程及方程組中。下面是一個使
用C++的實現:
int
exGcd(int a, int b, int &x, int
&y)
{
if(b ==
0)
{
x = 1;
y = 0;
return a;
}
int r =
exGcd(b, a % b, x, y);
int t =
x;
x =
y;
y = t - a
/ b * y;
return
r;
}
把這個實現和Gcd的遞迴實現相比,發現多了下面的x,y賦值過程,這就是擴充歐幾裡德演算法的精髓。
可以這樣思考:
對於a' = b,
b' = a % b 而言,我們求得 x, y使得 a'x + b'y = Gcd(a', b')
由於b' = a
% b = a - a / b * b (註:這裡的/是程式設計語言中的除法)
那麼可以得到:
a'x + b'y
= Gcd(a', b') ===>
bx + (a - a / b * b)y = Gcd(a', b') = Gcd(a, b)
===>
ay +b(x - a / b*y) = Gcd(a, b)
因此對於a和b而言,他們的相對應的p,q分別是
y和(x-a/b*y).
在網上看了很多關於不定方程方程求解的問題,可都沒有說全,都只說了一部分,看了好多之後才真正弄清楚不定方程的求解全過程,步驟如下:
求a * x
+ b * y = n的整數解。
1、先計算Gcd(a,b),若n不能被Gcd(a,b)整除,則方程無整數解;否則,在方程兩邊同時除以Gcd(a,b),得到新的不定方程a'
* x + b' * y = n',此時Gcd(a',b')=1;
2、利用上面所說的歐幾裡德演算法求出方程a' * x + b' * y = 1的一組整數解x0,y0,則n' * x0,n' *
y0是方程a' * x + b' * y = n'的一組整數解......餘下全文>>
 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.