The Luckiest numbe
题目:
在满足|x| + |y|最小时候,让a*|x| + b*|y|最小。求:|x| + |y|最小值。
算法:
同余式的求解运用。
解体步骤:
1、先用gcd判断是否有解。(c%g == 0有解)
2、对式子求最简式。a‘ = a/g ; b‘ = b/g; c‘ = c/g;
3、运用扩展欧几里得求解x,y的值。
4、判断当x,y分别求得最小正整数解时候的大小。
5、确定最后答案。
处理过程中有一些细节:
1、对求的x,y并不是正确的x,y值。要x = x * c; y = y * c
2、保证x或y是正数.(x%b + b)%b \ (y%a + a)%a
/* 1、|x| + |y|最小 2、在1相同的时候a*|x| + b*|y|最小 */ #include <iostream> #include <cstdio> #include <cstring> #include <cmath> using namespace std; typedef long long LL; LL gcd(LL a,LL b){ return b?gcd(b,a%b):a; } void extgcd(LL a,LL b,LL& d,LL& x,LL& y){ if(!b) { d = a; x = 1; y = 0; } else { extgcd(b,a%b,d,y,x); y -= x * (a/b); } } int main() { LL a,b,c; while(cin >> a >> b >> c){ if(a == 0&&b == 0&&c == 0)break; LL d = gcd(a,b); a /= d; b /= d; c /= d; LL x,y; extgcd(a,b,d,x,y); LL x1,y1,x2,y2; //y 取得最小正整数 y1 = y * c; y1 = (y1 % a + a) % a; x1 = (c - b*y1) / a; if(x1 < 0) x1 = -x1; //砝码个数非负 //x取得最小正整数 x2 = x * c; x2 = (x2 % b + b) % b; y2 = (c - a*x2) / b; if(y2 < 0) y2 = -y2; if(x1 + y1 < x2 + y2){x = x1; y = y1;} else {x = x2; y = y2;} cout << x << " " << y << endl; } return 0; } /* 700 300 200 500 200 300 500 200 500 275 110 330 275 110 385 648 375 4002 3 1 10000 0 0 0 */
时间: 2024-10-11 00:17:13