POJ2142 The Balance

嘟嘟嘟

我一眼就知道是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 }
View Code

猜你喜欢

转载自www.cnblogs.com/mrclr/p/9776345.html