[POJ2142]The Balance

这几天补补数学····做点基础题

题目描述

现有质量为a和b的砝码,数量不限
要求在天平上称出质量为d的物品,天平左右均可放砝码
求一种可行方案,要求:放置砝码数量尽可能少;数量相同时,总质量尽可能少
不会无解

分析

明显转化为ax+by=c,现在问题是让|x|+|y|最小。
若其最小,此时x或y肯定是最小的正整数解,因为一个更优,我们让他一直减下去嘛。
naive的想法是x每次减b,y每次减a,但是这样最后减出来的不是最小的,因为a,b不一定互质,减的东西可以是b/gcd(a,b),那么a,b,c都除(a,b)就好了。

代码

#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>
using namespace std;
typedef double db;
typedef long long ll;
#define fo(i,j,k) for(i=j;i<=k;i++)
#define fd(i,j,k) for(i=j;i>=k;i--)
int a,b,c,d,x,y,t,i,k,ax,ay;
int exgcd(int a,int b)
{
    if (!b)
    {
        x=1;
        y=0;
        return a;
    }
    int d=exgcd(b,a%b);
    int xx=y;
    int yy=x-a/b*y;
    x=xx;y=yy;
    return d;
}
int main()
{
    freopen("1.in","r",stdin);
    while (1)
    {
        scanf("%d %d %d",&a,&b,&c);
        if (!a) break;
        d=exgcd(a,b);
        k=c/d;
        x=x*k;
        y=y*k;
        a/=d;
        b/=d;
        c/=d;
        //minimize x
        ax=(x%b+b)%b;
        ay=(c-ax*a)/b;
        //minimize y
        y=(y%a+a)%a;
        x=(c-y*b)/a;
        if (abs(x)+abs(y)<abs(ax)+abs(ay)||(abs(x)+abs(y)==abs(ax)+abs(ay)&&b<a)) ax=x,ay=y;
        printf("%d %d\n",abs(ax),abs(ay));
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值