利用扩展欧几里得求最小非负整数解

Posted Harris-H

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了利用扩展欧几里得求最小非负整数解相关的知识,希望对你有一定的参考价值。

用 e x g c d 求 a x + b y = g c d ( a , b ) 用exgcd求ax+by=gcd(a,b) exgcdax+by=gcd(a,b)的最小非负整数解

#include<bits/stdc++.h>
using namespace std;
int exgcd(int a,int b,int &x,int &y) //返回值是最大公约数. 
	if(b==0)
		x=1,y=0;
		return a;
	
	int ans=exgcd(b,a%b,x,y); //b和a%b的最大公约数等于a和b的最大公约数 所以直接返回ans 
	int tmp=x;     //这里求解的是  bx1+(a%b)y1=gcd    ay1+b(x1-a/by1)=gcd   x=y1, y=x1-a/b*y1 
	x=y;
	y=tmp-a/b*y;
	return ans; 

int main()
	int a,b,x,y,g;
	while(cin>>a>>b)
		 g=exgcd(a,b,x,y);
		 int b1=b/g;
		 printf("x=%d,b1=%d,g=%d\\n",x,b1,g);  //原始的通解为   x=x0-(b/gcd)t  y=y0+(a/gcd)t 
		 x=(x%b1+b1)%b1;//这步是为了求x的最小非负整数解。     
		 					//令 g=(b/gcd)  当x为负数且x的绝对值比g小时显然加上一个g就行了 
		 y=(g-a*x)/b; 		当x为负数且x的绝对值比g大时,相当要要多加个g,这里用取余实现 比如 x=-10,g=4  
		 //x要加上3个g才行 ,先取余x%g=-2,这取余就相当于在加g,加到能被下一个g加变为非负整数 
		 printf("x=%d,y=%d\\n",x,y);
	
	return 0;
 

以上是关于利用扩展欧几里得求最小非负整数解的主要内容,如果未能解决你的问题,请参考以下文章

POJ1061-青蛙的约会---扩展欧几里德算法求最小整数解

扩展欧几里得

扩展欧几里得模板

扩展欧几里得NOIP2012同余方程

模板01_数论_扩展欧几里得_求同余方程

扩展欧几里得模板