8.15.3 The Balance

任务描述

本关任务:Iyo Kiffa Australis 女士有一个天平,但只有两种砝码可以用来称量一剂药物。例如,用 300 毫克和 700 毫克的砝码来测量 200 毫克阿司匹林,她就要将 1700 毫克的砝码和药物放在天平的一边,并将 3 300 毫克的砝码放在天平的另一边,如 图3.2-1 所示。虽然她也可以将 4300 毫克的砝码放和药物放在天平的一边,两个 700 毫克的砝码放在天平的另一边,如图3.2-2 所示,但她不会选择这个方案,因为使用更多的砝码不太方便。

,

图3.2-1

图3.2-2

编程要求

根据提示,在右侧编辑器补充代码。

测试说明

输入说明: 输入是一系列的测试用例。每个测试用例一行,给出 3 个用空格分隔的正整数 a , bd ,并满足以下关系:a≠ba<=10000,b<=10000,而且d<=50000。本题设定,您可以使用 a 毫克和 b 毫克的砝码组合来称量 d 毫克;也就是说,您不需要考虑“无解”的情况。 输入结束由一行表示,该行给出 3 个由空格分隔的零。这一行不是测试用例。

输出说明: 输出由一系列的行组成,每行对应一个测试用例(a, b, d)。一个输出行给出两个由空格分隔的非负整数 xy,且x和y要满足以下三个条件:

  • 使用 x 个 a 毫克的砝码和 y 个 b 毫克的砝码可以称量 d 毫克。
  • 在满足上述条件的非负整数对中,砝码总数(x + y)最小。
  • 在满足前两个条件的非负整数对中,砝码的总的质量(ax + by)最小。 输出中不能出现额外的字符(例如,额外的空格)。

平台会对你编写的代码进行测试:

测试输入:

 
  1. 700 300 200
  2. 500 200 300
  3. 500 200 500
  4. 275 110 330
  5. 275 110 385
  6. 648 375 4002
  7. 3 1 10000
  8. 0 0 0

预期输出:

 
  1. 1 3
  2. 1 1
  3. 1 0
  4. 0 3
  5. 1 1
  6. 49 74
  7. 3333 1
    //请使用C语言或者C++完成解答
    #include <iostream>
    #include <stdio.h>
    using namespace std;
    int gcd(int a,int b) //计算和返回GCD(a,b)
    {
        return b?gcd(b,a%b):a;
    }
    
    int ex_gcd(int a,int b,int &x,int &y){ //使用扩展的欧几里德算法计算和返回不定方程ax+by=GCD(a,b)的整数根(x,y)和GCD(a,b)
        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)){ //输入测试用例(即使用a毫克和b毫克的砝码组合来称量d毫克),直至输入0 0 0 为止
            if(a==0&&b==0&&d==0)break;
            q=gcd(a,b);//计算a,b的最大公约数
            //对于不定整数方程ax+by=d,若d%GCD(a,b)=0,则该方程存在整数解,否则不存在整数解
            a=a/q;b=b/q;d=d/q;//不定式两边同除GCD(a,b)(题目一定有解,可以整除)得到新不定方程:ax+by=d
            q=ex_gcd(a,b,x,y);
            x1=x*d;          //设天平左边放x个a毫克的砝码
            x1=(x1%b+b)%b;   //计算x的最小值x1
            y1=(d-a*x1)/b;   //根据x1计算b毫克的砝码数y1
            if(y1<0){        //若y1小于0,则y1个b毫克的砝码放天平右边,否则y1个b毫克的砝码放天平左边
                y1=-y1;
            }
            y2=y*d;              //计算b毫克砝码放天平左边的最少个数y2
            y2=(y2%a+a)%a;
            x2=(d-b*y2)/a;       //根据y2计算a毫克的砝码数x2
            if(x2<0){            //若x2小于0,则x2个a毫克的砝码放天平右边
                x2=-x2;
            }
            if(x1+y1<x2+y2){     //输出两边的砝码总数最少的方案
                printf("%d %d\n",x1,y1);
            }
            else{
                printf("%d %d\n",x2,y2);
            }
        }
        return 0;
    }
    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值