砝码称重

砝码称重问题

问题:4个砝码,每个重量都是整数克,总重量为40克,放在天平上可以称出1~40克的物体。求这4个砝码各多少克。

1. 问题分析

设4个砝码的重量分别为w1、w2、w3、w4,则w1+w2+w3+w4=40,且w1,w2,w3,w4均为正整数。
假设不相等(假设w1<w2<w3<w4),故砝码中最大为34克。

称重的天平有物体盘和砝码盘,称重时,若砝码只放在砝码盘,则
物体质量=砝码盘砝码质量
但若砝码盘和物体盘中都放置了砝码,则
物体质量=砝码盘砝码质量-物体盘砝码质量

从1~40,任意一个数,都应该能找到相应的砝码放置方法。砝码只有4个,且每次称重时,这4个砝码只能出现0次或者1次,且砝码要么在物体盘,要么在砝码盘,要解该问题,应该转换思路。
假设砝码在物体盘,认定其出现-1次
假设砝码在砝码盘,认定其出现1次
若该次称重,不需要该砝码,认定其出现0次

设4个砝码在每次称重中出现的次数分别为x1,x2,x3,x4,则只有-1、0、1这三种取值

如上分析,找到的砝码组合个数应该为40个(即1~40中的任意一个数都有对应的砝码组合)

2. C++版

  1. /************************************************************************  
  2.  * 4个砝码,每个重量都是整数克,总重量为40克,放在天平上可以称出1~40克的  
  3.  * 物体。求这4个砝码各多少克。  
  4.  * C++版  
  5.  ************************************************************************/   
  6. #include <stdio.h>   
  7.   
  8. class  CWeight  
  9. {  
  10.     int  w1,w2,w3,w4;     //砝码的重量   
  11.   
  12.     //砝码总重量   
  13.     static   const   int  TOTALWEIGHT=40;  
  14.   
  15.     //4个砝码,w1+w2+w3+w4=40,且w1,w2,w3,w4均为整数,假设不相等(假设w1<w2<w3<w4)故最大为34   
  16.     static   const   int  MAXWEIGHT=34;  
  17. public :  
  18.     CWeight(){w1=w2=w3=w4=0;}  
  19.     ~CWeight(){}  
  20.   
  21.     void  Calculate();  
  22.     bool  weight( int  w1, int  w2, int  w3, int  w4);  
  23.     void  output( int  w1, int  w2, int  w3, int  w4);  
  24. };  
  25.   
  26. void  CWeight::Calculate()  
  27. {  
  28.     int  w1,w2,w3,w4;  
  29.     for  (w1=1;w1<=MAXWEIGHT;w1++)  
  30.     {  
  31.         for  (w2=w1+1;w2<=MAXWEIGHT;w2++)  
  32.         {  
  33.             for  (w3=w2+1;w3<=MAXWEIGHT;w3++)  
  34.             {  
  35.                 for  (w4=w3+1;w4<=MAXWEIGHT;w4++)  
  36.                 {  
  37.                     if  (w1+w2+w3+w4==TOTALWEIGHT)  
  38.                     {  
  39.                         if  (weight(w1,w2,w3,w4))  
  40.                         {  
  41.                             printf("w1=%d w2=%d w3=%d w4=%d/n" ,w1,w2,w3,w4);  
  42.                             output(w1,w2,w3,w4);  
  43.                         }                         
  44.                     }  
  45.                 }  
  46.             }  
  47.         }  
  48.     }  
  49. }  
  50.   
  51. //从1~40,不管哪个重量都要找到相应的砝码放置方法   
  52. //w1,w2,w3,w4分别为4个砝码的重量   
  53. bool  CWeight::weight( int  w1, int  w2, int  w3, int  w4)  
  54. {  
  55.     int  w;   //物体重量   
  56.       
  57.     //砝码只有4个,且每次称重时,这4个砝码只能出现0次或者1次   
  58.     //出现时,砝码要么在物体盘,要么在砝码盘,要解该问题,转换思路   
  59.     //假设砝码在物体盘,认定其出现-1次   
  60.     //假设砝码在砝码盘,认定其出现1次   
  61.     //若该次称重,不需要该砝码,认定其出现0次   
  62.     //4个砝码在每次称重中出现的次数   
  63.     int  x1,x2,x3,x4;     //只有-1,0,1这三种取值   
  64.   
  65.     int  count=0;         //找到的砝码组合个数   
  66.   
  67.     //对1~40中的每个重量,都要找到相应的砝码组合   
  68.     //若有一个w(1<=w<=TOTALWEIGHT)没有找到相应的砝码组合,则表明该组砝码值不是所求   
  69.     for  (w=1;w<=TOTALWEIGHT;w++)   
  70.     {  
  71.         for  (x1=-1;x1<=1;x1++)  
  72.         {  
  73.             for  (x2=-1;x2<=1;x2++)  
  74.             {  
  75.                 for  (x3=-1;x3<=1;x3++)  
  76.                 {  
  77.                     for  (x4=-1;x4<=1;x4++)  
  78.                     {  
  79.                         if  (w1*x1+w2*x2+w3*x3+w4*x4==w)  
  80.                         {  
  81.                             count++;  
  82.   
  83.                             //找到该重量对应的砝码组合后,继续下一个重量   
  84.                             x1=x2=x3=x4=2;  
  85.                         }  
  86.                     }  
  87.                 }  
  88.             }  
  89.         }  
  90.     }  
  91.   
  92.     //如果找到所有的1~TOTALWEIGHT的砝码组合,则该组砝码值即为所求   
  93.     if  (count==TOTALWEIGHT)  
  94.         return   true ;  
  95.     else   
  96.         return   false ;  
  97. }  
  98.   
  99. //输出1~40中每个重量对应的砝码组合(负数表示该砝码放在物体盘)   
  100. void  CWeight::output( int  w1, int  w2, int  w3, int  w4)  
  101. {  
  102.     int  w;   //物体重量   
  103.     int  x1,x2,x3,x4;     //只有-1,0,1这三种取值   
  104.   
  105.     //对1~TOTALWEIGHT中的每个重量,都要找到相应的砝码组合   
  106.     for  (w=1;w<=TOTALWEIGHT;w++)   
  107.     {  
  108.         for  (x1=-1;x1<=1;x1++)  
  109.         {  
  110.             for  (x2=-1;x2<=1;x2++)  
  111.             {  
  112.                 for  (x3=-1;x3<=1;x3++)  
  113.                 {  
  114.                     for  (x4=-1;x4<=1;x4++)  
  115.                     {  
  116.                         if  (w1*x1+w2*x2+w3*x3+w4*x4==w)  
  117.                         {  
  118.                             printf("w=%2d: " ,w);  
  119.                             if  (x1!=0)  
  120.                                 printf("%d " ,w1*x1);  
  121.                             if  (x2!=0)  
  122.                                 printf("%d " ,w2*x2);  
  123.                             if  (x3!=0)  
  124.                                 printf("%d " ,w3*x3);  
  125.                             if  (x4!=0)  
  126.                                 printf("%d " ,w4*x4);  
  127.                             printf("/n" );  
  128.   
  129.                             //继续下一个重量   
  130.                             x1=x2=x3=x4=2;  
  131.                         }  
  132.                     }  
  133.                 }  
  134.             }  
  135.         }  
  136.     }  
  137. }  
  138.   
  139. int  main()  
  140. {  
  141.     CWeight wei;  
  142.     wei.Calculate();  
  143.   
  144.     return  0;  
  145. }  

    

3. C#版

  1. /************************************************************************  
  2.  * 4个砝码,每个重量都是整数克,总重量为40克,放在天平上可以称出1~40克的  
  3.  * 物体。求这4个砝码各多少克。  
  4.  * C#版  
  5.  ************************************************************************/   
  6. using  System;  
  7. using  System.Collections.Generic;  
  8. using  System.Text;  
  9.   
  10. namespace  Weight  
  11. {  
  12.     class  Program  
  13.     {  
  14.         //砝码总重量   
  15.         const   int  TOTALWEIGHT = 40;  
  16.   
  17.         //4个砝码,w1+w2+w3+w4=40,且w1,w2,w3,w4均为整数,假设不相等(假设w1<w2<w3<w4)故最大为34   
  18.         const   int  MAXWEIGHT = 34;  
  19.   
  20.         static   void  Main( string [] args)  
  21.         {  
  22.             int  w1, w2, w3, w4;  
  23.             for  (w1 = 1; w1 <= MAXWEIGHT; w1++)  
  24.             {  
  25.                 for  (w2 = w1 + 1; w2 <= MAXWEIGHT; w2++)  
  26.                 {  
  27.                     for  (w3 = w2 + 1; w3 <= MAXWEIGHT; w3++)  
  28.                     {  
  29.                         for  (w4 = w3 + 1; w4 <= MAXWEIGHT; w4++)  
  30.                         {  
  31.                             if  (w1 + w2 + w3 + w4 == TOTALWEIGHT)  
  32.                             {  
  33.                                 if  (weight(w1, w2, w3, w4))  
  34.                                 {  
  35.                                     System.Console.WriteLine("w1={0} w2={1} w3={2} w4={3} " , w1, w2, w3, w4);  
  36.                                     output(w1, w2, w3, w4);  
  37.                                 }  
  38.                             }  
  39.                         }  
  40.                     }  
  41.                 }  
  42.             }  
  43.         }  
  44.   
  45.         //从1~40,不管哪个重量都要找到相应的砝码放置方法   
  46.         //w1,w2,w3,w4分别为4个砝码的重量   
  47.         static   bool  weight( int  w1,  int  w2,  int  w3,  int  w4)  
  48.         {  
  49.             int  w;   //物体重量   
  50.   
  51.             //砝码只有4个,且每次称重时,这4个砝码只能出现0次或者1次   
  52.             //出现时,砝码要么在物体盘,要么在砝码盘,要解该问题,转换思路   
  53.             //假设砝码在物体盘,认定其出现-1次   
  54.             //假设砝码在砝码盘,认定其出现1次   
  55.             //若该次称重,不需要该砝码,认定其出现0次   
  56.             //4个砝码在每次称重中出现的次数   
  57.             int  x1, x2, x3, x4;  //只有-1,0,1这三种取值   
  58.   
  59.             int  count = 0;       //找到的砝码组合个数   
  60.   
  61.             //对1~40中的每个重量,都要找到相应的砝码组合   
  62.             //若有一个w(1<=w<=TOTALWEIGHT)没有找到相应的砝码组合,则表明该组砝码值不是所求   
  63.             for  (w = 1; w <= TOTALWEIGHT; w++)  
  64.             {  
  65.                 for  (x1 = -1; x1 <= 1; x1++)  
  66.                 {  
  67.                     for  (x2 = -1; x2 <= 1; x2++)  
  68.                     {  
  69.                         for  (x3 = -1; x3 <= 1; x3++)  
  70.                         {  
  71.                             for  (x4 = -1; x4 <= 1; x4++)  
  72.                             {  
  73.                                 if  (w1 * x1 + w2 * x2 + w3 * x3 + w4 * x4 == w)  
  74.                                 {  
  75.                                     count++;  
  76.   
  77.                                     //找到该重量对应的砝码组合后,继续下一个重量   
  78.                                     x1 = x2 = x3 = x4 = 2;  
  79.                                 }  
  80.                             }  
  81.                         }  
  82.                     }  
  83.                 }  
  84.             }  
  85.   
  86.             //如果找到所有的1~TOTALWEIGHT的砝码组合,则该组砝码值即为所求   
  87.             if  (count == TOTALWEIGHT)  
  88.                 return   true ;  
  89.             else   
  90.                 return   false ;  
  91.         }  
  92.   
  93.         //输出1~40中每个重量对应的砝码组合(负数表示该砝码放在物体盘)   
  94.         static   void  output( int  w1,  int  w2,  int  w3,  int  w4)  
  95.         {  
  96.             int  w;   //物体重量   
  97.             int  x1, x2, x3, x4;  //只有-1,0,1这三种取值   
  98.   
  99.             //对1~TOTALWEIGHT中的每个重量,都要找到相应的砝码组合   
  100.             for  (w = 1; w <= TOTALWEIGHT; w++)  
  101.             {  
  102.                 for  (x1 = -1; x1 <= 1; x1++)  
  103.                 {  
  104.                     for  (x2 = -1; x2 <= 1; x2++)  
  105.                     {  
  106.                         for  (x3 = -1; x3 <= 1; x3++)  
  107.                         {  
  108.                             for  (x4 = -1; x4 <= 1; x4++)  
  109.                             {  
  110.                                 if  (w1 * x1 + w2 * x2 + w3 * x3 + w4 * x4 == w)  
  111.                                 {  
  112.                                     System.Console.Write("w={0}: " , w);  
  113.                                     if  (x1 != 0)  
  114.                                         System.Console.Write("{0} " , w1 * x1);  
  115.                                     if  (x2 != 0)  
  116.                                         System.Console.Write("{0} " , w2 * x2);  
  117.                                     if  (x3 != 0)  
  118.                                         System.Console.Write("{0} " , w3 * x3);  
  119.                                     if  (x4 != 0)  
  120.                                         System.Console.Write("{0} " , w4 * x4);  
  121.                                     System.Console.WriteLine();  
  122.   
  123.                                     //继续下一个重量   
  124.                                     x1 = x2 = x3 = x4 = 2;  
  125.                                 }  
  126.                             }  
  127.                         }  
  128.                     }  
  129.                 }  
  130.             }  
  131.         }  
  132.     }  
  133. }  

4. 运行结果

说明:第一行表示4个砝码的质量分别为1,3,9,27

         其他行,负数表示该砝码放在物体盘,正数表示该砝码放在砝码盘

w1=1 w2=3 w3=9 w4=27
w= 1: 1
w= 2: -1 3
w= 3: 3
w= 4: 1 3
w= 5: -1 -3 9
w= 6: -3 9
w= 7: 1 -3 9
w= 8: -1 9
w= 9: 9
w=10: 1 9
w=11: -1 3 9
w=12: 3 9
w=13: 1 3 9
w=14: -1 -3 -9 27
w=15: -3 -9 27
w=16: 1 -3 -9 27
w=17: -1 -9 27
w=18: -9 27
w=19: 1 -9 27
w=20: -1 3 -9 27
w=21: 3 -9 27
w=22: 1 3 -9 27
w=23: -1 -3 27
w=24: -3 27
w=25: 1 -3 27
w=26: -1 27
w=27: 27
w=28: 1 27
w=29: -1 3 27
w=30: 3 27
w=31: 1 3 27
w=32: -1 -3 9 27
w=33: -3 9 27
w=34: 1 -3 9 27
w=35: -1 9 27
w=36: 9 27
w=37: 1 9 27
w=38: -1 3 9 27
w=39: 3 9 27
w=40: 1 3 9 27

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值