Description
You are asked to help her by calculating how many weights are required.
Input
The end of the input is indicated by a line containing three zeros separated by a space. It is not a dataset.
Output
- You can measure dmg using x many amg weights and y many bmg weights.
- The total number of weights (x + y) is the smallest among those pairs of nonnegative integers satisfying the previous condition.
- The total mass of weights (ax + by) is the smallest among those pairs of nonnegative integers satisfying the previous two conditions.
No extra characters (e.g. extra spaces) should appear in the output.
Sample Input
700 300 200 500 200 300 500 200 500 275 110 330 275 110 385 648 375 4002 3 1 10000 0 0 0
Sample Output
1 3 1 1 1 0 0 3 1 1 49 74 3333 1
Source
題解:
這道題與模板題唯一的區別就是,他要求的"最小正整數解"不再是隻關注ax+by=c兩個解x,y中的任意一個,而是關注了|x|+|y|的值。其實學過這類函數的同學可以畫個W=|x|+|y|圖像試試,通過不斷平移,你會發現最小的整點一定是最靠近直線與座標軸交點的地方。因此我們就先解決ax+by=c對於x的最小正整數解,再解決對於y的最小正整數解,按照他的排序要求,找到最小的那個即可。
AC代碼:
#include<iostream>
#include<cstdio>
#define ll long long
using namespace std;
ll exgcd(ll a,ll b,ll &x,ll &y){
ll d;
if(b){d=exgcd(b,a%b,y,x);y-=a/b*x;return d;}
x=1;y=0;return a;
}
ll ab(ll x){
return x>0?x:-x;
}
ll w1,w2,c;
void work(){
ll d,anx,any,min1=2147483647,min2=2147483647,x,y;
d=exgcd(w1,w2,anx,any);anx=anx*c/d;any=any*c/d;
x=anx;y=any;
anx=(anx%(w2/d)+w2/d)%(w2/d);
any=any-(anx-x)/(w2/d)*(w1/d);
min1=ab(anx)+ab(any);min2=anx*w1+any*w2;
x=anx;y=any;
any=(any%(w1/d)+w1/d)%(w1/d);
anx=anx-(any-y)/(w1/d)*(w2/d);
if(min1>ab(anx)+ab(any)){
x=anx;y=any;
}
if(min1==ab(anx)+ab(any)){
if(min2>anx*w1+any*w2){
x=anx;y=any;
}
}
printf("%lld %lld\n",ab(x),ab(y));
}
int main(){
while(1){
scanf("%lld%lld%lld",&w1,&w2,&c);
if(w1==0&&w2==0&&c==0)return 0;
work();
}
return 0;
}