POJ - 2142 The Balance(扩展欧几里得求解不定方程)

d.用2种砝码,质量分别为a和b,称出质量为d的物品。求所用的砝码总数量最小(x+y最小),并且总质量最小(ax+by最小)。

s.扩展欧几里得求解不定方程。

设ax+by=d.

题意说不定方程一定有解。对于不定整数方程pa+qb=c,若 c mod Gcd(p, q)=0,则该方程存在整数解,否则不存在整数解。

也就是说,d mod gcd(a,b)=0.

a,b,d同时除以gcd(a,b)得到a'x+b'y=d';

用扩展欧几里德求出 a'x+b'y=gcd(a',b')=1的解(x,y),

那么原来这个a'x+b'y=d'的解就是(x*d',y*d')。

然后分两种情况来求就行了(假设物品放右边):

(1)令x是最小正整数,a放左边的最优解;(y<0代表b放右边)

(2)令y是最小正整数,b放左边的最优解;

两者中x+y小的就是结果。

c.

#include<iostream>
#include<stdio.h>
using namespace std;

int gcd(int a,int b){
    return b?gcd(b,a%b):a;
}

int ex_gcd(int a,int b,int &x,int &y){
    if(b==0){
        x=1;
        y=0;
        return a;
    }
    int d=ex_gcd(b,a%b,x,y);
    int t=x;
    x=y;
    y=t-a/b*y;
    return d;
}

int main(){

    int a,b,d;

    int q;//a,b的最大公约数
    int x,y;
    int x1,y1;
    int x2,y2;

    while(~scanf("%d%d%d",&a,&b,&d)){
        if(a==0&&b==0&&d==0)break;

        q=gcd(a,b);
        //这里 对于不定整数方程pa+qb=c,若 c mod Gcd(p, q)=0,则该方程存在整数解,否则不存在整数解。
        //不定方程:ax+by=d
        a=a/q;
        b=b/q;
        d=d/q;//题目一定有解,可以整除

        //不定方程:ax+by=d

        q=ex_gcd(a,b,x,y);//求的是ax+by=gcd(a,b)=1

        //令x是最小正整数,a放左边的最优解
        x1=x*d;
        x1=(x1%b+b)%b;//x变为最小正整数
        y1=(d-a*x1)/b;
        if(y1<0){
            y1=-y1;
        }

        //令y是最小正整数,b放左边的最优解
        y2=y*d;
        y2=(y2%a+a)%a;//y变为最小正整数
        x2=(d-b*y2)/a;
        if(x2<0){
            x2=-x2;
        }

        //x+y和最小
        if(x1+y1<x2+y2){
            printf("%d %d\n",x1,y1);
        }
        else{
            printf("%d %d\n",x2,y2);
        }

    }

    return 0;
}
View Code

 

posted @ 2016-03-10 16:51  gongpixin  阅读(366)  评论(0编辑  收藏  举报