扩展欧几里得算法------求解线性方程ax+by=c
扩展欧几里德算法是用来在已知a, b求解一组x,y,使它们满足等式: ax+by =gcd(a, b) =d(解一定存在,根据数论中的相关定理)。扩展欧几里德常用在求解模线性方程及方程组中。
<span style="font-size:14px;">int Extended_Euclid(int a,int b,int& x,int &y) { if(b==0) { x=1; y=0; return a; } int d=Extended_Euclid(b,a%b,x,y); int temp=x; x=y; y=temp-a/b*y; return d; } //用扩展欧几里得算法解线性方程ax+by=c; int solve(int a,int b,int c,int& x,int &y) { int d=Extended_Euclid(a,b,x,y); if(c%d) return false; int k=c/d; x*=k; y*=k;//求的只是其中一个解 return true; } 参考练习题:<a target=_blank href="http://acm.nyist.net/JudgeOnline/problem.php?pid=144">http://acm.nyist.net/JudgeOnline/problem.php?pid=144</a></span>
<span style="font-size:14px;"> #include<iostream> #include<time.h> #include<stdio.h> using namespace std; int gcd(int a,int b) { if(a==0)return b; return gcd(b%a,a); } int main() { int a,b,n,m; //freopen("2.txt","r",stdin); //freopen("1.txt","w",stdout); cin>>m; for(int i=0;i<m;i++){ scanf("%d %d %d",&a,&b,&n); if((n%gcd(a,b))==0) printf("Yes\n"); else printf("No\n"); } } </span>
题意:
给定x, k,求p, q使得:
思路:
利用扩展的欧几里得定理,ax + by = gcd(a, b);x, y一定有整数解。
ax1+by1=gcd(a,b)=gcd(b,a%b)=bx2+(a%b)y2=bx2+(a-(a/b)*b)y2
参考代码:
<span style="font-size:14px;">#include<cstdio> #include<cstring> #include<cstdlib> #include<cmath> #include<iostream> #include<algorithm> using namespace std; void gcdextend(int a,int b,int &d,int &x,int &y) { if(!b) { d=a; x=1; y=0; } else { gcdextend(b,a%b,d,y,x); y-=x*(a/b); } } int main() { int cc; cin>>cc; while(cc--) { int a,b,c,k; cin>>c>>k; a=(int )floor(1.0*c/k); b=(int )ceil(1.0*c/k); int d,x,y; gcdextend(a,b,d,x,y); x*=(c/d); y*=(c/d); cout<<x<<" "<<y<<endl; } } </span>