问题:
运行结果:
用天平称重时,我们希望用尽可能少的砝码组合称出尽可能多的重量。
如果只有5个砝码,重量分别是1,3,9,27,81。则它们可以组合称出1到121之间任意整数重量(砝码允许放在左右两个盘中)。
本题目要求编程实现:对用户给定的重量,给出砝码组合方案。
例如:
用户输入:
5
程序输出:
9-3-1
用户输入:
19
程序输出:
27-9+1
要求程序输出的组合总是大数在前小数在后。
可以假设用户的输入的数字符合范围1~121。
思路:
对于每个xi,可以乘以一个系数ki,再求和。
ki的数值无外乎:-1 0 1
这样,因为标准砝码的数量的很少的,我们就可以多层循环暴力组合ki来求解。代码(比较狗):
#include <stdio.h>
#include <stdlib.h>
int main()
{
int x[6]= {0,81,27,9,3,1};
int k1[3]= {0,-1,1};//为每个砝码设一个0,-1,1的数组,以便结合
int k2[3]= {0,-1,1};
int k3[3]= {0,-1,1};
int k4[3]= {0,-1,1};
int k5[3]= {0,-1,1};
int jie[6];
int n,i,j1,j2,j3,j4,j5,sum,judge=1;
scanf("%d",&n);
for(j1=0; j1<=3; j1++)//五个0,1,-1,进行穷举
{
for(j2=0; j2<=3; j2++)
for(j3=0; j3<=3; j3++)
for(j4=0; j4<=3; j4++)
for(j5=0; j5<=3; j5++)
{
if(judge==0)
break;
sum=0;
jie[1]=k1[j1]*x[1];//jie[]表示相乘后的结果
jie[2]=k2[j2]*x[2];
jie[3]=k3[j3]*x[3];
jie[4]=k4[j4]*x[4];
jie[5]=k5[j5]*x[5];
for(i=1; i<=5; i++)
sum+=jie[i];//结果相加
if(sum==n)//判断是否等于所给重量
{
for(i=1; i<6; i++)
if(jie[i]!=0)
printf("%d",jie[i]);
judge=0;
break;
}
}
}
return 0;
}
运行结果:
小结:这个题思路还有很多,例如贪心,回朔,以及根据砝码重量为3的倍数来求解等。
纠正一个错误,上面的程序只能输出减号,如果两个数相加则不会显示加号,所以现改正如下:
#include <stdio.h>
#include <stdlib.h>
int main()
{
int x[6]= {0,81,27,9,3,1};
int k1[3]= {0,-1,1};//为每个砝码设一个0,-1,1的数组,以便结合
int k2[3]= {0,-1,1};
int k3[3]= {0,-1,1};
int k4[3]= {0,-1,1};
int k5[3]= {0,-1,1};
int jie[6];
int n,i,j1,j2,j3,j4,j5,sum,judge=1;
int a=0;
scanf("%d",&n);
for(j1=0; j1<=3; j1++)//五个0,1,-1,进行穷举
{
for(j2=0; j2<=3; j2++)
for(j3=0; j3<=3; j3++)
for(j4=0; j4<=3; j4++)
for(j5=0; j5<=3; j5++)
{
if(judge==0)
break;
sum=0;
jie[1]=k1[j1]*x[1];//jie[]表示相乘后的结果
jie[2]=k2[j2]*x[2];
jie[3]=k3[j3]*x[3];
jie[4]=k4[j4]*x[4];
jie[5]=k5[j5]*x[5];
for(i=1; i<=5; i++)
sum+=jie[i];//结果相加
if(sum==n)//判断是否等于所给重量
{
for(i=1; i<6; i++)
{
if(jie!=0)
{
if(jie[i]<0)
printf("%d",jie[i]);
else
{
if(jie[i]>0)
{
if(a==0)
{
printf("%d",jie[i]);
a=1;
}
else
printf("+%d",jie[i]);
}
}
}
}
judge=0;
break;
}
}
}
return 0;
}