题目地址: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