任务描述
本关任务:Iyo Kiffa Australis 女士有一个天平,但只有两种砝码可以用来称量一剂药物。例如,用 300
毫克和 700
毫克的砝码来测量 200
毫克阿司匹林,她就要将 1
个 700
毫克的砝码和药物放在天平的一边,并将 3
个 300
毫克的砝码放在天平的另一边,如 图3.2-1 所示。虽然她也可以将 4
个 300
毫克的砝码放和药物放在天平的一边,两个 700
毫克的砝码放在天平的另一边,如图3.2-2 所示,但她不会选择这个方案,因为使用更多的砝码不太方便。
图3.2-1
图3.2-2
编程要求
根据提示,在右侧编辑器补充代码。
测试说明
输入说明: 输入是一系列的测试用例。每个测试用例一行,给出 3
个用空格分隔的正整数 a
, b
和 d
,并满足以下关系:a≠b
,a<=10000,b<=10000,
而且d<=50000
。本题设定,您可以使用 a
毫克和 b
毫克的砝码组合来称量 d
毫克;也就是说,您不需要考虑“无解”的情况。 输入结束由一行表示,该行给出 3
个由空格分隔的零。这一行不是测试用例。
输出说明: 输出由一系列的行组成,每行对应一个测试用例(a, b, d
)。一个输出行给出两个由空格分隔的非负整数 x
和 y
,且x和y要满足以下三个条件:
- 使用
x
个a
毫克的砝码和y
个b
毫克的砝码可以称量d
毫克。 - 在满足上述条件的非负整数对中,砝码总数(
x + y
)最小。 - 在满足前两个条件的非负整数对中,砝码的总的质量(
ax + by
)最小。 输出中不能出现额外的字符(例如,额外的空格)。
平台会对你编写的代码进行测试:
测试输入:
700 300 200
500 200 300
500 200 500
275 110 330
275 110 385
648 375 4002
3 1 10000
0 0 0
预期输出:
1 3
1 1
1 0
0 3
1 1
49 74
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; }