用天平称重时,我们希望用尽可能少的砝码组合称出尽可能多的重量。
如果只有5个砝码,重量分别是1,3,9,27,81。则它们可以组合称出1到121之间任意整数重量(砝码允许放在左右两个盘中)。
本题目要求编程实现:对用户给定的重量,给出砝码组合方案。
例如:
用户输入:
5
程序输出:
9-3-1
用户输入:
19
程序输出:
27-9+1
输入:
41
输出:
81-27-9-3-1
要求程序输出的组合总是大数在前小数在后。
可以假设用户的输入的数字符合范围1~121。
思路:
int[] fama砝码的重量;
int weight要求的重量。
Stack stack储存比weight小的数;
例如:int[] fama = {1, 3, 9, 27, 81};int weight=50;stack={1,3,9,27};
执行action(50,sb)//sb stringbuffer;
1.如果weight > stack元素之和,说明81在 sb中。所以 sb = 81-(;运行aciton(81-50,sb);
2.如果 weight = stack元素之和,直接sb = 1+3+9+27;
3.如果 weight< stack元素之和,把27出栈顶,运行aciton(50,sb);
所以执行1了,运行action(31,sb)
执行1,31> 1+3+9,所以找到27
如果 27>31 sb=81-(27-
如果27<31 sb = 81-(27+
重复操作
最后结果是
81+(27-(9-(3-(1))));
剩下的就是拆括号了。
public class TianPing {
Integer[] fama;
int weight;
Stack<Integer> stack=new Stack<Integer>();
StringBuffer sb = new StringBuffer();
public TianPing(Integer[] array,int weight){
this.fama = array;
this.weight = weight;
for(int a:fama){
if(a <= weight){
stack.push(a);
}
}
action(weight,sb);System.out.println(sb.toString());
}
public void action(int weight,StringBuffer sb){
int totalWeight = 0;
while(weight <= stack.peek()){
if(weight==stack.peek()){
sb.append(stack.peek());
return;
}
stack.pop();
}
for(int i=0;i<stack.size();i++){
totalWeight+=stack.elementAt(i);
}
if(weight>totalWeight){
if(fama[stack.size()]>weight){
sb.append(fama[stack.size()]+"-(");
action(fama[stack.size()]-weight,sb);
sb.append(")");
} else if(fama[stack.size()]<weight){
sb.append(fama[stack.size()]+"+");
action(weight - fama[stack.size()],sb);
}
} else if(weight < totalWeight){
stack.pop();
action(weight,sb);
} else if(weight == totalWeight){
while(!stack.isEmpty()){
sb.append(stack.pop()+"+");
}
sb.setLength(sb.length()-1);
return;
}
}
public static void main(String args[]){
Integer []array = {1,3,9,27,81};
for(int i=1;i<=121;i++){
new TianPing(array,i);
}
}
}