poj2142

//1.ax+by=gcd(a,b)利用这个公式可以得到一个不等式的一组解 x.y.利用扩展欧几里得算法 可以求出:
//ax+by==a*y1+b*(x1-(a/b)*y1):上一深度的x等于下一深度的y1,上一深度的y等于下一深度的x1-(a/b)*y1
//2.然而对于一般的不等式ax+by==c。它的解就是 x1=x*(c/gcd(a,b)) y1=y*(c/gcd(a,b));
//3.然而所有的解,假设d=gcd(a,b),那么 x=x0+b/d*t; y=y0-a/d*t;其中t为任意整数
//3只知道公式 不知道是怎么推出来的。
//题意:给你一种天平,改天平只有两种重量的砝码,要求你成出重量为c的物品,问需要多少a和b,即a与b的数量和重量和最小
//注意两边都可以放砝码
//求|x|+|y|的最小值,带入公式|x0+b/d*t|+|y0-a/d*t|求解  当y0-a/d*t==0的时候,最小值|x|+|y|一定是在t=y0*d/a附近。
#include<stdio.h>
int x,y;
int a,b,c;
int gcd(int a,int b)
{
    int d;
    if(b==0)
    {
        x=1;y=0;
        return a;
    }
    else
    {
        d=gcd(b,a%b);
        int t=x;
        x=y;
        y=t-(a/b)*y;
    }
    return d;
}
int swap(int *a,int *b)
{
    int t;
    t=*a;
    *a=*b;
    *b=t;
}
int abs(int a)
{
    if(a<0)
     return -a;
    return a;
}
int main()
{
    int ans,d;
    int x1,x2,y1,y2,i;
    while(scanf("%d%d%d",&a,&b,&c)!=EOF)
    {
        if(a==0&&b==0&&c==0)
           break;
        int flag=0;
        if(a<b)
        {
            flag=1;
            swap(&a,&b);
        }
        d=gcd(a,b);
        x=x*c/d;
        y=y*c/d;
        int t=y*d/a;
        ans=9999999;
        for(i=t-3;i<=t+3;i++)
        {
            x2=x+(b/d)*i;
            y2=y-(a/d)*i;
            if(abs(x2)+abs(y2)<ans)
            {
                ans=abs(x2)+abs(y2);
                x1=x2;
                y1=y2;
            }
        }
        if(!flag)
          printf("%d %d\n",abs(x1),abs(y1));
        else
          printf("%d %d\n",abs(y1),abs(x1));
    }
    return 0;
}

你可能感兴趣的:(poj2142)