您的位置:首页 > 其它

扩展欧几里德算法

2012-05-24 01:37 141 查看
扩展欧几里德算法求解线性方程ax+by=c

令d=(a,b) 若此方程有解 则 c|d 否则无解

通解x=x0+b/d*t,y=y0+a/d*t;

令k=b/d

则可求得x最小正数解为(x%k+k)%k

最大负数解为(x%k-k)%k

//POJ 1061 水题
#include<cstdio>
using namespace std;
__int64 X,Y;
__int64 ex_euclid(__int64 a,__int64 b){
if(b==0){
X=1;
Y=0;
return a;
}
__int64 d=ex_euclid(b,a%b);
__int64 t=X;
X=Y;
Y=t-(a/b)*Y;
return d;
}
int main(){
__int64 x,y,m,n,L;
while(scanf("%I64d%I64d%I64d%I64d%I64d",&x,&y,&m,&n,&L)!=EOF){
__int64 a=n-m,b=L,c=x-y;
__int64 d=ex_euclid(a,b);
if(c%d){
printf("Impossible\n");
continue;
}
X*=(c/d);
Y*=(c/d);
__int64 K=b/d;
X=(X%K+K)%K;
printf("%lld\n",X);
}
return 0;
}


//POJ 2115 纯水~
#include<cstdio>
using namespace std;
__int64 x,y;
__int64 ex_euclid(__int64 a,__int64 b){
if(b==0){
x=1;
y=0;
return a;
}
int d=ex_euclid(b,a%b);
int t=x;
x=y;
y=t-a/b*y;
return d;
}
int main(){
__int64 A,B,C,k;
while(scanf("%I64d%I64d%I64d%I64d",&A,&B,&C,&k)!=EOF){
if(!(A||B||C||k))
break;
__int64 a=C,b=((__int64)1)<<k,c=B-A;
__int64 d=ex_euclid(a,b);
if(c%d){
printf("FOREVER\n");
continue;
}
x*=(c/d);
y*=(c/d);
__int64 s=b/d;
x=(x%s+s)%s;
printf("%I64d\n",x);
}
return 0;
}


/* POJ 2142 个人认为是个很好的题 有助于理解扩展欧几里德算法
有点忘记这题的细节怎么处理了 有空补上 代码先贴出来
*/
#include<cstdio>
#include<cmath>
#include<cstdlib>
using namespace std;
int X,Y;
int ex_euclid(int a,int b){
if(b==0){
X=1;
Y=0;
return a;
}
int d=ex_euclid(b,a%b);
int t=X;
X=Y;
Y=t-a/b*Y;
return d;
}
int main(){
int a,b,c;
while(scanf("%d%d%d",&a,&b,&c)!=EOF){
if(a==0&&b==0&&c==0)
break;
int f=1;
if(a<b){
int m=a;
a=b;
b=m;
f=0;
}
int d=ex_euclid(a,b);
X*=(c/d);
Y*=(c/d);
int k=a/d;
int y1=(Y%k+k)%k;
int x1=(c-b*y1)/a;
int y2=(Y%k-k)%k;
int x2=(c-b*y2)/a;
//		printf("%d %d %d %d\n\n",x1,y1,x2,y2);
int ans1=abs(x1)+abs(y1);
int ans2=abs(x2)+abs(y2);
if(ans1!=ans2){
if(ans1<ans2){
if(f)
printf("%d %d\n",abs(x1),abs(y1));
else
printf("%d %d\n",abs(y1),abs(x1));
}
else{
if(f)
printf("%d %d\n",abs(x2),abs(y2));
else
printf("%d %d\n",abs(y2),abs(x2));
}
}
else{
int res1=a*abs(x1)+b*abs(y1);
int res2=a*abs(x2)+b*abs(y2);
if(res1<res2){
if(f)
printf("%d %d\n",abs(x1),abs(y1));
else
printf("%d %d\n",abs(y1),abs(x1));
}
else{
if(f)
printf("%d %d\n",abs(x2),abs(y2));
else
printf("%d %d\n",abs(y2),abs(x2));
}
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: