The Balance
题意:给定一个两个砝码以及一个物品(物品可以在天平左右)求能使天平达到平衡的最优解。
题解:构造方程ax+by=c,对于x,y取正负都符合题意。转化为求|x| + |y| 的最优解 x=x0+k*b/g y=y0-k*a/g;
对于|x0+k*b/g|+|y0-k*a/g|的最优解一定在 x0+k*b/g=0 以及 y0-k*a/g=0,这两个k之间,遍历一下就好了。(分段函数)
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
void exgcd(ll a,ll b,ll &d,ll &x,ll &y)
{
if (!b)
{
d=a;
x=1;
y=0;
return;
}
exgcd(b,a%b,d,y,x);
y-=a/b*x;
}
int main()
{
ll a,b,c,d,x,y,ansx,ansy,xx,yy,zz,ans,t;
while (scanf("%lld%lld%lld",&a,&b,&c))
{
if (a==0&&b==0&&c==0)
{
break;
}
exgcd(a,b,d,x,y);
x=x*c/d;
y=y*c/d;
ans=0x3f3f3f3f;
t=y/(a/d);
zz=-x/(b/d);
ansx=abs(x);
ansy=abs(y);
ans=ansx+ansy;
for (ll i=min(zz,t)-1;i<=max(zz,t)+1;i++){
yy=y-a/d*i;
//printf("%lld\n",i);
if (yy<0) yy=-yy;
xx=x+b/d*i;
if (xx<0) xx=-xx;
if (ans>xx+yy){
ans=xx+yy;
ansx=xx;
ansy=yy;
}else{
if (ans==xx+yy){
if (a*ansx+b*ansy>a*abs(xx)+b*abs(yy)){
ansx=xx;
ansy=yy;
}
}
}
}
printf("%lld %lld\n",ansx,ansy);
}
return 0;
}