参考博客 https://www.cnblogs.com/My-Sunshine/p/4830171.html 这个博主写的非常详细!!! O(∩_∩)O~~
一,题意:
有两个类型的砝码,质量分别为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 中的最小值。
三,步骤:
1,由题意得出两个方程
i,ax1 - by1 = d ;
ii,bx2 - ay2 = d 。
2,代入算法,解出两个方程的解(x1,y1)、(x2,y2),并求出最小x1和x2,以及相对应的y1,y2.
(详细步骤请参照本博客poj1061或者poj2115)。
3, 判断步骤
i,x1+y1最小时,输出x1,y1
ii,x2+y2最小时,输出y2,x2。 *此处为y2在前面输出,因为x2+y2最小时,第一个输入的a对应的是y2。
#include<iostream>
#include<cmath>
#define ll long long
using namespace std;
int exgcd(int a,int b,int &x,int &y) // 板子
{
if(b==0)
{
x=1;
y=0;
return a;
}
int g=exgcd(b,a%b,y,x);
y-=(a/b)*x;
return g;
}
// ax-by=c
int main()
{
int a,b,c;
while(cin>>a>>b>>c){
if(a==0&&b==0&&c==0)
break;
// 求ax+by=c 的解x
int x,y;
int d=exgcd(a,b,x,y);
x=x*c/d;
int t=b/d;
if(x>=0){
x=x%t;
}
else{
x=(x%t+t)%t;
}
y=fabs((a*x-c)/b);
//求bx+ay=c 的解x
int x1,y1;
swap(a,b);// 交换a b的值
d=exgcd(a,b,x1,y1);
x1=x1*c/d;
t=b/d;
if(x1>=0){
x1=x1%t;
}
else{
x1=(x1%t+t)%t;
}
y1=fabs((a*x1-c)/b); // abs->int型 fabs -> float型
if(x1+y1>x+y)
{
cout<<x<<" "<<y<<endl;
}
else
{
cout<<y1<<" "<<x1<<endl;
}
}
return 0;
}