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

版权声明:原创文章,转载请注明出处 https://blog.csdn.net/hza419763578/article/details/88125697

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; 
}

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初值如何,最终返回的都是方程的一个解
 */

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;
}

猜你喜欢

转载自blog.csdn.net/hza419763578/article/details/88125697