用天平称重时,我们希望用尽可能少的砝码组合称出尽可能多的重量。
如果只有5个砝码,重量分别是1,3,9,27,81 则它们可以组合称出1到121之间任意整数重量(砝码允许放在左右两个盘中)。 本题目要求编程实现:对用户给定的重量,给出砝码组合方案。 例如: 用户输入: 5 程序输出: 9-3-1 用户输入: 19 程序输出: 27-9+1 要求程序输出的组合总是大数在前小数在后。 可以假设用户的输入的数字符合范围1~121。
思路:
观察:
1 = 1;
2 = 3 - 1;
3 = 3;
4 = 3 +1;
5 = 9 - 3 -1;
......
可得规律
2>3/2 5 > 9/2
由此可得当目标重量值大于最大砝码值的1/2时必然会出现减号
代码:
/**
* 递归求法
* @author Administrator
*
*/
public class Main {
public static void main(String[] args) {
for(int i = 1 ; i <= 100 ; i++ ){
System.out.println(i+" : "+f(i));
}
}
/**
* 递归思路:
* 1.算出可能用到的最大砝码
* 2.如果最大砝码和重物相等返回砝码质量
* 3.如果最大砝码的质量的二分之一大于重物则使用最大砝码的前一级砝码"+"重物减去最大砝码的前一级砝码的递归结果
* 4.如果最大砝码的质量的二分之一小于重物则使用最大砝码的前一级砝码"-"最大砝码减去重物的递归结果
* 5.注意去负号时的符号取反
* @param x
* @return
*/
static String f(int x){
int a = 1;//最小单位
while(a<x) a*=3;
if(a==x) return ""+x;
if(x<=a/2) return a/3 + "+" +f(x-a/3);
return a +"-"+reve(f(a-x));
}
static String reve(String s){
s = s.replace('-', '%');
s = s.replace('+', '-');
s = s.replace('%', '+');
return s;
}
}