A guy has a balance. This balance has only two weights, a and B. Now I want to name an item with a weight of c and ask how much a and B you need at least, the answer needs to meet the requirements of a plus B's quantity and minimum, and their weight is also minimum. (You can place weights on both disks)
Analysis:
At the beginning, I thought it was just a matter of Motion Planning or search.
Assume that we use x weights and y weights. Therefore, the balance should meet the requirements of ax + by = c. When x and y are positive, they are placed on the other side of item c. If they are negative, they are placed on the same side of item c.
Therefore, the question becomes the minimum value of | x | + | y |. X and y are the solutions of the infinitus ax + by = c.
We have just mentioned the same formula for the solutions of x and y, that is
X = x0 + B/d * t
Y = y0-a/d * t
Do you subconsciously want to give up all the solutions, take | x | + | y | minimum? Obviously it does not work, careful analysis: | x | + | y | = | x0 + B/d * t | + | y0-a/d * t |, we stipulate that a> B (if a <B, we will exchange a B). From this formula, we can easily find: | x0 + B/d * t | is monotonic increasing, | y0-a/d * t | is monotonic decreasing, and because we set a> B, the slope side of the subtraction is greater than the increasing slope, so the whole function is faster than increasing. However, due to the effect of the absolute value symbol, the final function is increasing progressively. That is to say, the function is concave, first decreasing and then increasing. So when is the minimum? Obviously it is y0-a/d * t = 0, so our minimum value | x | + | y | it must be near t = y0 * d/, I took the smallest value in the range of around five o'clock (it is said that both the left and right vertices can be used, but I tried wa ). Generally, this type of question involves more enumeration points, just in case !!!
# Include <iostream> # include <cstdio> # include <cstring> # include <string> # include <cstdlib> # include <cmath> # include <vector> # include <list> # include <deque> # include <queue> # include <iterator> # include <stack> # include <map> # include <set> # include <algorithm> # include <cctype> # include <sstream> using namespace std; typedef long LL; const int N = 10010; const ll ii = 100000000; const int IN F = 0x3f3f3f; const double PI = acos (-1.0); int ext_gcd (int a, int B, int & x, int & y) {int t, ret; if (! B) {x = 1, y = 0; return a;} ret = ext_gcd (B, a % B, x, y); t = x, x = y, y = t-a/B * y; return ret;} int gcd (int m, int n) {int t; while (n) {t = m % n; m = n; n = t;} return m;} int main () {int I, j, a, B, c; while (scanf ("% d", & a, & B, & c) & (a + B + c) {int f = 0; // tag AB exchange if (a <B) f = 1, swap (a, B); int x, y, t, d; d = ext_gcd (a, B, x, y); x = x * c/d; y = y * c/d; t = y * d/a; int x1, y1, Min = INF, xx, yy; for (I = t-5; I <t + 5; I ++) // scan around 5 points {x1 = abs (x + B/d * I); y 1 = abs (y-a/d * I); if (x1 + y1 <Min) {Min = x1 + y1; xx = x1; yy = y1 ;}} if (f) printf ("% d \ n", yy, xx); else printf ("% d \ n", xx, yy );} return 0 ;} /**/# include <iostream> # include <cstdio> # include <cstring> # include <string> # include <cstdlib> # include <cmath> # include <vector> # include <list> # include <deque> # include <queue> # include <iterator> # include <stack> # include <map> # include <set> # include <algorithm> # includ E <cctype> # include <sstream> using namespace std; typedef long LL; const int N = 10010; const ll ii = 100000000; const int INF = 0x3f3f3f; const double PI = acos (-1.0); int ext_gcd (int a, int B, int & x, int & y) {int t, ret; if (! B) {x = 1, y = 0; return a;} ret = ext_gcd (B, a % B, x, y); t = x, x = y, y = t-a/B * y; return ret;} int gcd (int m, int n) {int t; while (n) {t = m % n; m = n; n = t;} return m;} int main () {int I, j, a, B, c; while (scanf ("% d", & a, & B, & c) & (a + B + c) {int f = 0; // tag AB exchange if (a <B) f = 1, swap (a, B); int x, y, t, d; d = ext_gcd (a, B, x, y); x = x * c/d; y = y * c/d; t = y * d/a; int x1, y1, Min = INF, xx, yy; for (I = t-5; I <t + 5; I ++) // scan around 5 points {x1 = abs (x + B/d * I ); y1 = abs (y-a/d * I); if (x1 + y1 <Min) {Min = x1 + y1; xx = x1; yy = y1 ;}} if (f) printf ("% d \ n", yy, xx); else printf ("% d \ n", xx, yy );} return 0 ;}/**/