#include <cstdio> #include <cstring> #include <cmath> #include <cstdlib> typedef long long ll; int extended_euclid(int a,int b,int& x,int& y) { int d = a; if(b){ d = extended_euclid(b,a % b,y,x); y -= (a / b) * x; } else{ x = 1; y = 0; } return d; } void solve(int a,int b,int d,int& x,int& y) { int g = extended_euclid(a,b,x,y); x *= d / g; int t = b / g; x = (x % t + t) % t;
y = abs((a * x - d) / b); } int main() { int a,b,c,x1,x2,y1,y2; while(scanf("%d %d %d",&a,&b,&c) != EOF && (a || b || c)){ solve(a,b,c,x1,y1); solve(b,a,c,x2,y2); if(x1 + y1 < x2 + y2) printf("%d %d\n",x1,y1); else printf("%d %d\n",y2,x2); } return 0; }
真是精髓啊: 对于ax+by=c, x=x0+(lcm/a) * c y=y0-(lcm/b) * c 对于lcm/a, lcm*gcd=a*b lcm/a=b/gcd 所以x=x0+(b/g)*c x%t的作用是不能让x比b/gcd大,但是考虑到x可能是负数 所以 xm = (x % t + t) % t;,让xm成为最小的可行的正数 y = (a*xm-d)/b 所以在第二遍吧b当成a后,bx+ay=d, b找到的也是最小的可行的正数
扩欧 非常精妙 ax+by=d, 并令abc(a)+abs(b)最小
最新推荐文章于 2023-10-16 23:18:58 发布