扩展欧几里德算法
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
令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; }