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 <stdio.h>
#include <math.h>
#include <string.h>
#include <stdlib.h>
#include <iostream>
#include <sstream>
#include <algorithm>
#include <set>
#include <queue>
#include <stack>
#include <map>
#include <bitset>
#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;
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-07 08:26:22

POJ 2142-The Balance(扩展欧几里德)的相关文章

POJ 2142 - The Balance [ 扩展欧几里得 ]

题意: 给定 a b n找到满足ax+by=n 的x,y 令|x|+|y|最小(等时令a|x|+b|y|最小) 分析: 算法一定是扩展欧几里得. 最小的时候一定是 x 是最小正值 或者 y 是最小正值 (简单的证明应该是分x,y 符号一正一负,和x,y符号都为正来考虑) 扩欧解的方程为 ax+by = gcd(a, b) 先简化问题,等价为扩欧求的是 a'x+b'y = 1 则原方程等价为 a'x+b'y = n' (a, b, n 全部除以gcd(a, b) ) 先解x为最小正值的时候 x =

POJ 2142 The Balance【扩展欧几里德】

题意:有两种类型的砝码,每种的砝码质量a和b给你,现在要求称出质量为c的物品,要求a的数量x和b的数量y最小,以及x+y的值最小. 用扩展欧几里德求ax+by=c,求出ax+by=1的一组通解,求出当x取最小合法正整数解时y的取值,当y小于0时,说明应该放在a的另一边,变为正值.同理当y取最小时,可得到另一组解,比较两组解,取最小即可. #include<stdio.h> int ex_gcd(int a,int b,int &x,int &y){ if(!b){ x=1,y=

POJ2142 The Balance (扩展欧几里德)

本文为博主原创文章,欢迎转载,请注明出处 www.cnblogs.com/yangyaojia The Balance 题目大意  你有一个天平(天平左右两边都可以放砝码)与重量为a,b(1<=a,b<=10000)的两种砝码.让你求出一种方案称出重为c(1<=c<=50000)的物品,如有多种方案,请输出两种砝码需要数量的总和最小的方案. 输入 有若干行,每行三个数,a,b,c. 结束时用0 0 0表示. 输出 若干行,每行两个数,表示每个询问中a的数量与b的数量 如果无解输出 

poj2142-The Balance(扩展欧几里德算法)

一,题意: 有两个类型的砝码,质量分别为a,b;现在要求称出质量为d的物品, 要用多少a砝码(x)和多少b砝码(y),使得(x+y)最小.(注意:砝码位置有左右之分). 二,思路: 1,砝码有左右位置之分,应对比两种情况 i,a左b右,得出方程 ax1 - by1 = d ; ii,b左a右,得出方程 bx2 - ay2 = d . 2,利用扩展欧几里德算法,解出(x1,y1).(x2,y2),并求出最小x1和x2,以及相对应的y1,y2. 3,输出x1+y1和x2+y2 中的最小值. 三,步骤

POJ 2142 The Balance(exgcd)

嗯... 题目链接:http://poj.org/problem?id=2142 AC代码: 1 #include<cstdio> 2 #include<iostream> 3 4 using namespace std; 5 6 inline int _abs(int x){ 7 if(x < 0) return -x; 8 return x; 9 } 10 11 inline void exgcd(int a, int b, int &g, int &x,

POJ 2142 The Balance

The Balance Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 6325   Accepted: 2787 Description Ms. Iyo Kiffa-Australis has a balance and only two kinds of weights to measure a dose of medicine. For example, to measure 200mg of aspirin usi

POJ 2115 C Looooops (扩展欧几里德 + 线性同余方程)

分析:这个题主要考察的是对线性同余方程的理解,根据题目中给出的a,b,c,d,不难的出这样的式子,(a+k*c) % (1<<d) = b; 题目要求我们在有解的情况下求出最小的解,我们转化一下形式. 上式可以用同余方程表示为  a + k*c = (b) % (1<<d)   <-->  k*c = (b-a) % (1<<d)(中间应该是全等号,打不出来…).这就是我们想要的同余方程,根据我的个人习惯,我把它转化为线性方程的形式. -->   c*

POJ 2142:The Balance_扩展欧几里得(多组解)

先做出两个函数的图像,然后求|x|+|y|的最小值.|x|+|y|=|x0+b/d *t |+|y0-a/d *t| 这个关于t的函数的最小值应该在t零点附近(在斜率大的那条折线的零点附近,可以观察出来).以下三种情况中,函数最小值都应该出现在B点附近./* 对于不定整数方程xa+yb=c,若 c mod Gcd(a, b)=0,则该方程存在整数解,否则不存在整数解. 上面已经列出找一个整数解的方法,在找到x * a+y * b = Gcd(a, b)的一组解x0,y0后 ,/*x * a+y

POJ 2891-Strange Way to Express Integers(扩展欧几里德)

题目地址:POJ 2891 题意:给你k组同余关系,每组包含一个ai和ri,让你找出一个最小的数m,满足m%a1=r1,m%a2=r2.......m%ak=rk. 思路:纵观上述公式,很熟悉,其实就是求两两公式之间的最小值,例如K=3,那么先求第一组和第二组的最小,然后合并第一组和第二组,然后用合并之后的再和第三组找最小,最后的结果就是最终的结果.也就是这个题分两部分来完成. 1.找出两组最小.对于m%a1=r1和m%a2=r2可以得出两个公式m=a1*x+r1,m=a2*y+r2(x,y相当