[Ybt gold medal navigation 8-6-2] [POJ 2142] balance problem / The Balance

The balance problem / The Balance

Topic link: ybt gold medal navigation 8-6-2 / POJ 2142

General idea

Give you a balance and two masses of weights (infinite), and then ask you how to weigh a product with a given mass.
To ensure that it can be weighed out, the number of weights required is as small as possible. If the number of weights is the same, the total mass of the weights used is required to be as small as possible.
Output the number of weights used by two weights.

Ideas

First of all, we thought that it is impossible for a weight to appear on both sides.
Because if so, we can remove the same number on the left and right sides, so that the original mass can still be weighed, and the number of weights used and the total mass are better.

Then we try to formulate a formula:
ax + by = c ax+by=cax+by=c
a , b a,b a,b is the mass of the two weights respectively)
(x, yx, yx,The absolute value of y is the number they use, if it is positive, it is placed on the left, otherwise it is placed on the right)
(ccc is the quality of the item you want to weigh)

Then you find that it is an indeterminate equation, then we use extended Euclidean to solve it.
That's because the problem must have a solution, so it doesn't matter whether there is a solution or not.

Then we consider how to choose the best option.
The first is the number of weights, so you must have the smallest number of choices.

Then you can calculate the value of the other side when the two sides are the smallest.
Then compare which is better and choose whichever is better.

Code

#include<cstdio>
#define ll long long

using namespace std;

ll a, b, c, xy, yx;
ll x, y, ans1, ans2;

ll exgcd(ll a, ll &x, ll b, ll &y) {
    
    //扩展欧几里得
	if (!b) {
    
    
		x = 1;
		y = 0;
		return a;
	}
	
	ll re = exgcd(b, y, a % b, x);
	y -= a / b * x;
	return re;
}

int main() {
    
    
	scanf("%lld %lld %lld", &a, &b, &c);
	while (a || b || c) {
    
    
		ll gcd = exgcd(a, x, b, y);//算出通解
		
		a /= gcd;
		b /= gcd;
		c /= gcd;
		x = ((x * c) % b + b) % b;//之前除了c,现在乘回来
		y = ((y * c) % a + a) % a;
		
		xy = (c - x * a) / b;//算出x最小或y最小时另一个的值
		yx = (c - y * b) / a;
		if (xy < 0) xy = -xy;//小于0,说明是放在另一边,个数一样
		if (yx < 0) yx = -yx;
		
		if (x + xy < y + yx || ((x + xy == y + yx) && (a * x + b * xy < a * yx + b * y))) {
    
    
			printf("%lld %lld\n", x, xy);//x最小的优
		}
		else {
    
    
			printf("%lld %lld\n", yx, y);//y最小的优
		}
		
		scanf("%lld %lld %lld", &a, &b, &c);
	}
	
	return 0;
}

Guess you like

Origin blog.csdn.net/weixin_43346722/article/details/114172844