gcd歐幾里德演算法/extgcd擴充套件歐幾里德演算法以及在解不定方程中的應用
阿新 • • 發佈:2019-01-13
這個應該是我在noip前就應該會的東西 ,但是當時也許只是記下了程式碼吧 ,現在有諸多的不理解。後來藉著書和幾篇部落格弄懂了並小證了一下,鑑於網上有些部落格關於這個的寫的真的不好看,所以自己來總結一下,順帶以後也能看。
順帶一提,
歐幾里德演算法
輾轉相除法求最大公約數問題,同可求最小公倍數。
既然是輾轉相除法,自然就是%%%,%到互相整除為止。程式碼也很詳盡簡潔。
int regulargcd(int x,int y)
{
return y==0?x:(regulargcd(y,x%y));
}
最小公倍數為兩數之積除以他們的最大公約數,相信大家都能明白。
擴充套件歐幾里德演算法
我之前一直困惑的是它為什麼可以求不定方程的解,後來基本明白了:
給定一個形如方程
我們知道
所以說,假設我們有
再推到一般,若
然後接下來我們考慮特殊解的情況:
於是我們來找
於是原方程解為
這樣我們就能遞迴地計算方程的解了。
int extgcd(int a,int b,int &x,int &y )
{
if(b==0)
{
x=1;
y=0;
return a;
}
else
{
int ans;
ans=extgcd(b,a%b,x,y);
int tmp=x;
x=y;
y=tmp-(a/b)*y;
return ans;
}
}
不定方程不是有很多解嗎?是的,這只是最小解。設最小解為
while(x<=0)
{
x+=(b/res);
}
printf("%d\n",x);
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <vector>
#include <queue>
//zoj3609 AC
using namespace std;
int extgcd(int a,int b,int &x,int &y)
{
if(b==0)
{
x=1;
y=0;
return a;
}
else
{
int ans;
ans=extgcd(b,a%b,x,y);
int tmp=x;
x=y;
y=tmp-(a/b)*y;
return ans;
}
}
int regulargcd(int x,int y)
{
return y==0?x:(regulargcd(y,x%y));
}
int main()
{
int a,b;
int cas;
scanf("%d",&cas);
for(int z=0;z<cas;z++)
{
scanf("%d%d",&a,&b);
int x,y;
if(regulargcd(a,b)==1)
{
int res=extgcd(a,b,x,y);
if(x>0)
{
printf("%d\n",x);
}
else
{
while(x<=0)
{
x+=(b/res);
}
printf("%d\n",x);
}
}
else
{
printf("Not Exist\n");