poj 2142 The Balance

#include <iostream>
using namespace std;
int x0,y0,g;
void extend_gcd(int a,int b)
{
if(b==0)
{
x0
=1;y0=0;g=a;
}
else
{
extend_gcd(b,a
%b);
int tmp=x0;
x0
=y0;
y0
=tmp-(a/b)*y0;
}
}
int main()
{
int a,b,d,x,y;bool tag;
while(cin>>a>>b>>d&&a)
{
int res1,res2;tag=1;
if(a<b)
{
tag
=0;swap(a,b);
}
extend_gcd(a,b);
x
=x0*d/g; y=y0*d/g;
int t1,t2;
t1
=y*g/a;
if(t1*a/g-y>=0)
t1
--;
t2
=t1+1;
int r1_x,r1_y,r2_x,r2_y;

r1_x
=abs(x+b/g*t1);r1_y=abs(y-a/g*t1);
r2_x
=abs(x+b/g*t2);r2_y=abs(y-a/g*t2);

if(r1_x+r1_y>r2_x+r2_y||( r1_x+r1_y==r2_x+r2_y && a*r1_x+b*r1_y > a*r2_x+b*r2_y )) //当(|x|+|y|)相等时,比较(a|x|+b|y|)哪个小
{
if(tag)
cout
<<r2_x<<" "<<r2_y<<endl;
else
cout
<<r2_y<<" "<<r2_x<<endl;
}
else
{
if(tag)
cout
<<r1_x<<" "<<r1_y<<endl;
else
cout
<<r1_y<<" "<<r1_x<<endl;
}
}
return 0;
//给定 a b d找到满足ax+by=d 的令|x|+|y|最小
//参考线性同余方程 g=gcd(a,b) , ax0+by0=gcd(a,b)
//方程的一组解: x=x0*d/g; y=y0*d/g; 方程的全部解:x..=x+b/g*t y..=y-a/g*t
//|x|+|y|= | x + b/g*t | + | y - a/g*t |
//这个关于t的函数的最小值应该在| y - a/g*t |为零附近,即t=y*g/a
//在 y*g/a 附近的两整数点里取t,再直接验证这两点即可。
}

  

posted on 2011-07-18 00:05  sysu_mjc  阅读(175)  评论(0编辑  收藏  举报

导航