poj 2142 拓展欧几里得 砝码

xiaoxiao2021-02-27  284

一,题意:   有两个类型的砝码,质量分别为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.   x 为最小正整数时候的解 x = (x % a + a) % a   和y为最小整数时候的解 然后比较即可     (详细步骤请参照本博客poj1061或者poj2115)。   3, 判断步骤     i,x1+y1最小时,输出x1,y1     ii,x2+y2最小时,输出y2,x2。

#include <iostream> #include <cstdio> #include <cstring> using namespace std; int Extend_gcd(int a,int b,int &x,int &y) { if(!b) { x=1,y=0; return a; } else { int r=Extend_gcd(b,a%b,y,x); y-=x*(a/b); return r; } } int main() { int a,b,n; while(cin>>a>>b>>n) { if(a+b+n==0) break; int x,y; int gcd=Extend_gcd(a,b,x,y); int vx=x*(n/gcd); int t=b/gcd; vx=(vx%t+t)%t; int vy=(n-a*vx)/b; if(vy<0) vy=-vy; y=(y*n/gcd); t=a/gcd; y=(y%t+t)%t; x=(n-b*y)/a; if(x<0) x=-x; if(x+y>vx+vy) { x=vx,y=vy; } printf("%d %d\n",x,y ); } }
转载请注明原文地址: https://www.6miu.com/read-1732.html

最新回复(0)