POJ 2142-The Balance(扩展欧几里德)

题目地址:POJ 2142
题意:有两种类型的砝码质量分别为a和b,要求称出质量为d的物品,要求a的数量x和b的数量y的和x+y最小,若有多个x+y的值,取ax+by最小的。
思路:我们应该求ax+by=d。这里我们应用扩展欧几里德求出ax+by=gcd(a,b),那么ax/gcd(a,b)+by/gcd(a,b)=1,然后求出来特解,令x=x*n,把x转化为最小正值,即x=(x%b+b)%b,求出此时的y=(d-ax)/b,若求出的y是负值,把y变成正的,因为砝码的位置涉及左右之分。同理求出y为最小正值是x的解,然后比较两组的值就好了。。

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#pragma comment(linker, "/STACK:102400000,102400000")
using namespace std;
typedef __int64 LL;
const int inf=0x3f3f3f3f;
const double pi= acos(-1.0);
const double esp=1e-6;
using namespace std;
int gcd(int a,int b)
{
    while(b!=0){
        int r=b;
        b=a%b;
        a=r;
    }
    return a;
}
void exgcd(int a,int b,int &x,int &y)
{
    if(b==0){
        x=1,y=0;
        return ;
    }
    exgcd(b,a%b,x,y);
    int t=x;
    x=y;
    y=t-(a/b)*y;
}
int main()
{
    int a,b,d;
    int x,y;
    int xx,yy;
    int tx,ty;
    while(~scanf("%d %d %d",&a,&b,&d)){
        if(!a&&!b&&!d) break;
        int G=gcd(a,b);
        a/=G;
        b/=G;
        d/=G;
        exgcd(a,b,x,y);
        xx=x*d;
        xx=(xx%b+b)%b;
        yy=(d-a*xx)/b;
        if(yy<0) yy=-yy;
        ty=y*d;
        ty=(ty%a+a)%a;
        tx=(d-b*ty)/a;
        if(tx<0) tx=-tx;
        if(tx+ty>xx+yy){
            tx=xx;
            ty=yy;
        }
        printf("%d %d\n",tx,ty);
    }
    return 0;
}

你可能感兴趣的:(数论,Poj)