POJ2142The Balance扩展欧几里得

题目: http://poj.org/problem?id=2142

 

题意:有两种类型的砝码质量分别为,要求称出质量为的物品,要求的数量的数量的和

     最小,如果有多个最小值,取最小的。

 

分析:扩展欧几里得求出特解后,把转化为最小正值,即,若

     求出的为负值,则把变正,意思就是砝码放置的位置有左右之分,可以左面的减去右面的,也可以右面

     的减去左面的。同理,再求出为最小合法正值时的解,将这两种情况比较取小的即可。


收获:

这题最初求出来的一组特解x,y中必定是一正一负的,因为砝码的数量不可能为负,所以就相当于用扩展欧几里德求一组解,且|x| + |y|最小。由拓展欧几里德求得x = x0 + b/gcd(a,b)*t, y = y0 + a/gcd(a,b)*t  (其中t为任意整数) ,经过分析所求x+y或者|x| + |y|是满足单调性的,只要x越小或者y越小就行,两者比较下即可。


#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
int gcd(int a, int b)
{
    return b ? gcd(b, a%b) : a;
}
void extend_Euclid(int a, int b, int &x, int &y)
{
    if(b == 0)
    {
        x = 1;
        y = 0;
        return ;
    }
    extend_Euclid(b, a%b, x, y);
    int tmp = x;
    x = y;
    y = tmp - (a/b)*y;
}
int main()
{
    int a, b, n, x, y;
    while(scanf("%d%d%d", &a, &b, &n) != EOF)
    {
        if(a+b+n == 0) break;
        int d = gcd(a, b);
        a /= d;
        b /= d;
        n /= d;
        extend_Euclid(a, b, x, y);
        int tx = x * n;
        tx = (tx + b*n) % b;
        int ty = (n - a*tx) / b;
        if(ty < 0) ty = -ty;
        y *= n;
        y = (y + a*n) % a;
        x = (n - b*y) / a;
        if(x < 0) x = -x;
        if(x + y > tx + ty)
        {
            x = tx;
            y = ty;
        }
        printf("%d %d\n", x, y);
    }
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值