题意:一个家伙有一种天平,这种天平只有两种重量的砝码a和b,现在要称出重量为c的物品,问你至少需要多少a和b,答案需要满足a的数量加上b的数量和最小,并且他们的重量和也要最小。(两个盘都可以放砝码)。
思路:扩展欧几里得、然后暴力枚举。
题目链接:http://poj.org/problem?id=2142
View Code
1 #include <cstdio> 2 #include <cmath> 3 #include <cstdlib> 4 #include <cstring> 5 #include <string> 6 #include <algorithm> 7 #include <iostream> 8 using namespace std; 9 10 int a,b,c,x,y; 11 12 int exgcd(int a,int b){ 13 int t,d; 14 if(b==0){ 15 x=1; 16 y=0; 17 return a; 18 } 19 d=exgcd(b,a%b); 20 t=x; 21 x=y; 22 y=t-(a/b)*y; 23 return d; 24 } 25 26 int main(){ 27 28 // freopen("data.in","r",stdin); 29 // freopen("data.out","w",stdout); 30 31 int sum1,sum2,ans1,ans2; 32 int a1,b1,c1; 33 while(scanf("%d%d%d",&a,&b,&c),a||b||c){ 34 int d=exgcd(a,b); 35 a1=a/d; b1=b/d; c1=c/d; 36 x=x*c/d; 37 y=y*c/d; 38 sum1=abs(x)+abs(y); sum2=abs(x)*a+abs(y)*b; 39 ans1=abs(x); 40 ans2=abs(y); 41 for(int i=-50000;i<=50000;i++){ // x1=x+b/d*t; y1=y-a/d*t; 42 int s1=abs(x+i*b1)+abs(y-i*a1); 43 int s2=abs(x+i*b1)*a+abs(y-i*a1)*b; 44 if(s1<sum1||s1==sum1&&s2<sum2){ 45 sum1=s1; 46 sum2=s2; 47 ans1=abs(x+i*b1); ans2=abs(y-i*a1); 48 } 49 } 50 printf("%d %d\n",ans1,ans2); 51 } 52 return 0; 53 }