0
点赞
收藏
分享

微信扫一扫

算法笔记5.7 拓展欧几里得算法


1.拓展欧几里得算法

求: 不定方程ax+by=gcd(a,b)的整数解   其中a,b均为整数

核心代码:

int exGcd(int a,int b,int& x,int& y){
if(b==0){
x=1;
y=0;
return a;
}
int g=exGcd(b,a%b,x,y);
int temp=x;
x=y;
y=temp-(a/b)*y;
return g;
}

样例:

#include<iostream>     
#include<cstdio>
using namespace std;

/*
* 拓展欧几里得算法
* ax+by=gcd(a,b)的解
*
* return gcd(a,b)
* 不论a,b初值如何,最终返回的都是方程的一个解
*/

int exGcd(int a,int b,int& x,int& y){
if(b==0){
x=1;
y=0;
return a;
}
int g=exGcd(b,a%b,x,y);
int temp=x;
x=y;
y=temp-(a/b)*y;
return g;
}
int main(){
int a,b,x,y;
cout<<"请输入a,b:";
while(cin>>a>>b){
int gcd=exGcd(a,b,x,y);
printf("%dx+%dy=%d\n该不定方程的解如下:\n", a,b,gcd);
int Tx=b/gcd;
int Ty=a/gcd;
x=(x%Tx+Tx)%Tx;
y=(gcd-a*x)/b;
printf("x最小非负整数解:x=%d y=%d\n",x,y);
printf("通解:x=%d+%d*K y=%d-%d*K\n",x,Tx,y,Ty);
}
return 0;
}

算法笔记5.7 拓展欧几里得算法_拓展欧几里得

 

 

2.ax+by=c  普通不定方程的求解

普通不定方程:ax+by=c  均为整数 
c%gcd(a,b)==0  否则无解

(x0,y0)是ax+by=gcd(a,b)的一组解 并设:gcd=gcd(a,b)
则(x,y)=(x0*c/gcd,y0*c/gcd)  是不定方程ax+by=c的一组解
通解:
    x'=x+b/gcd*k=cx0/gcd+b/gcd*k
    y'=y+a/gcd*k=cy0/gcd-a/gcd*k     
    k为任意整数

#include<iostream>     
using namespace std;

int exGcd(int a,int b,int& x,int& y){
if(b==0){
x=1;
y=0;
return a;
}
int g=exGcd(b,a%b,x,y);
int temp=x;
x=y;
y=temp-(a/b)*y;
return g;
}

int main(){
int a,b,x,y,c;
cout<<"请输入a,b:";
while(cin>>a>>b>>c){
int gcd=exGcd(a,b,x,y);
if(c%gcd!=0){
printf("%dx+%dy=%d\n该不定方程无解\n", a,b,c);
continue;
}
printf("%dx+%dy=%d\n该不定方程的解如下:\n", a,b,c);
int Tx=b/gcd;
int Ty=a/gcd;
x=c*x/gcd;
y=c*y/gcd;
x=(x%Tx+Tx)%Tx;
y=(c-a*x)/b;
printf("x最小非负整数解:x=%d y=%d\n",x,y);
printf("通解:x=%d+%d*K y=%d-%d*K\n",x,Tx,y,Ty);
}
return 0;
}


/*
* 拓展欧几里得算法
* ax+by=c的解
*
* return gcd(a,b)
* 不论a,b初值如何,最终返回的都是方程的一个解
*/

算法笔记5.7 拓展欧几里得算法_#include_02

 

 

3.同余式ax≡c(mod m)的求解

若:    (a-b)%m==0
则:    a与b模m同余
同余式:a≡b(mod m) 
-------------------------------------------------------
    ax≡c(mod m)
即:(ax-c)%m=0
    ax-c=my   //y为任意整数
    ax+my=c      //另y=-y
-------------------------------------------------------
转化为问题二了,且只用求x即可
    ax+my=gcd(a,m)解为x0,y0
则:    ax+my=c
    一个特解为:x=cx0/gcd(a,m), y=cy0/gcd(a,m)
x通解:x'=x+m/gcd(a,m)*k
         =cx0/gcd(a,m)+m/gcd(a,m)*k  //完全由a,m,c决定
         

#include<iostream>     
using namespace std;

int exGcd(int a,int b,int& x,int& y){
if(b==0){
x=1;
y=0;
return a;
}
int g=exGcd(b,a%b,x,y);
int temp=x;
x=y;
y=temp-(a/b)*y;
return g;
}

int main(){
int a,c,m,x,y;
printf("请输入a,c,m:");
while(cin>>a>>c>>m){
int gcd=exGcd(a,m,x,y);
if(c%gcd!=0){
printf("%d≡%d(mod%d)\n", a,c,m);
printf("即:(%dx-%d)%%%d=0无解\n",a,c,m);
continue;
}
x=c*x/gcd;
printf("%d≡%d(mod%d)\n", a,c,m);
printf("即:(%dx-%d)%%%d=0的解\n",a,c,m);
printf("特解:x=%d\n", x);
printf("通解:x=%d+%d*k\n", x,m/gcd);
}

return 0;
}

算法笔记5.7 拓展欧几里得算法_#include_03

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

举报

相关推荐

0 条评论