我一眼就知道是exgcd,但是还是想的不太周全。
应该分两种情况:
1.a在左边,b在右边。那么得出方程ax - by = d。然后就是正常的exgcd求解了:
解得ax + by = (a, b)的解x', y'。
算出ax + by = d的解x = x' * d / (a, b)
算出x的最小正整数解xmin = x % (b / (a, b))。写的时候为了保证是正数,应该写成xmin = (x % t + t) % t (t = b / (a, b))。
当x确定时,y就确定。把x代入ax - by = d,算出y,y要取绝对值,因为把一个砝码放在右边x个等于放在左边-x个。
2.a在右边,b在左边
同理算出x2, y2。
输出x1 + y1, x2 + y2较小的一对。
1 #include<cstdio> 2 #include<iostream> 3 #include<cmath> 4 #include<algorithm> 5 #include<cstring> 6 #include<cstdlib> 7 #include<cctype> 8 #include<vector> 9 #include<stack> 10 #include<queue> 11 using namespace std; 12 #define enter puts("") 13 #define space putchar(' ') 14 #define Mem(a, x) memset(a, x, sizeof(a)) 15 #define rg register 16 typedef long long ll; 17 typedef double db; 18 const int INF = 0x3f3f3f3f; 19 const db eps = 1e-8; 20 //const int maxn = ; 21 inline ll read() 22 { 23 ll ans = 0; 24 char ch = getchar(), last = ' '; 25 while(!isdigit(ch)) {last = ch; ch = getchar();} 26 while(isdigit(ch)) {ans = ans * 10 + ch - '0'; ch = getchar();} 27 if(last == '-') ans = -ans; 28 return ans; 29 } 30 inline void write(ll x) 31 { 32 if(x < 0) x = -x, putchar('-'); 33 if(x >= 10) write(x / 10); 34 putchar(x % 10 + '0'); 35 } 36 37 int a, b, d; 38 void exgcd(int a, int b, int &x, int &y, int &c) 39 { 40 if(!b) c = a, x = 1, y = 0; 41 else {exgcd(b, a % b, y, x, c); y -= a / b * x;} 42 } 43 void work(int a, int b, int &x, int &y, int &c) 44 { 45 exgcd(a, b, x, y, c); 46 x *= d / c; 47 int t = b / c; 48 x = (x % t + t) % t; 49 y = abs((a * x - d) / b); 50 } 51 52 int main() 53 { 54 while(scanf("%d%d%d", &a, &b, &d) && a && b && d) 55 { 56 int xf, yf, xs, ys, c; 57 work(a, b, xf, yf, c); 58 work(b, a, ys, xs, c); 59 if(xf + yf < xs + ys) write(xf), space, write(yf), enter; 60 else write(xs), space, write(ys), enter; 61 } 62 63 return 0; 64 }