用天平称重时,我们希望用尽可能少的砝码组合称出尽可能多的重量。
* 如果只有5个砝码,重量分别是 1,3,9,27,81。
* 则它们可以组合称出1到121之间任意整数重量(砝码允许放在左右两个盘中)
* 例如:
* 用户输入:
* 5
* 程序输出:
* 9-3-1
* 用户输入:
* 19
* 程序输出:
* 27-9+1
* 输入:
* 41
* 输出:
* 81-27-9-3-1
* 如果只有5个砝码,重量分别是 1,3,9,27,81。
* 则它们可以组合称出1到121之间任意整数重量(砝码允许放在左右两个盘中)
* 例如:
* 用户输入:
* 5
* 程序输出:
* 9-3-1
* 用户输入:
* 19
* 程序输出:
* 27-9+1
* 输入:
* 41
* 输出:
* 81-27-9-3-1
* </pre>
package com.ccl.algo;
/**
* @author changlun.cheng
*
* <pre>
* 用天平称重时,我们希望用尽可能少的砝码组合称出尽可能多的重量。
* 如果只有5个砝码,重量分别是 1,3,9,27,81。
* 则它们可以组合称出1到121之间任意整数重量(砝码允许放在左右两个盘中)
* 例如:
* 用户输入:
* 5
* 程序输出:
* 9-3-1
* 用户输入:
* 19
* 程序输出:
* 27-9+1
* 输入:
* 41
* 输出:
* 81-27-9-3-1
* </pre>
*/
public class Weight {
/**
* 思路一:把1,3,9,27,81,-1,-3,-9,-27求全排列, 记下值在1-121之间的数并打印;<br/>
* 思路二:把1,3,9,27,81转为3进制数; <br/>
* 思路三:贪心算法;<br/>
*
* 思路四: (1) 被称物质的质量计算的数学原理:设被称物质m放在天平左边,根据天平平衡原理,左边质量应等于天平右边质量。 <br/>
* (2) 问题关键在于算法中如何体现砝码放在天平左边
* ,右边或没有参加称量。这里可以用-1,1,0表示砝码放在天平左,右和没有参加称量,再没有其他数,所以称为三进制数,每个砝码都有这样的三种状态。<br/>
* (3)
* 被称物体质量计算:m=a*81+b*27+c*9+d*3+e。这里a,b,c,d,e分别表示81,27,9,3,1克的砝码是放在天平的左边,
* 右边或是没用<br/>
*/
public final int weight[] = new int[] { 1, 3, 9, 27, 81 };
public java.util.List<Integer> list = new java.util.ArrayList<Integer>();
public final int length = 5;
/**
* 思路二
*
* @param wei
*/
public void ternary(int wei) {
int w = 81, i = 4;
int warray[] = new int[] { 0, 0, 0, 0, 0 };
/* 求wei对应的3进制数 */
while (wei != 0) {
if (w > wei) {
w /= 3;
i--;
} else {
wei -= w;
warray[i]++;
}
}
/**
* 修改,逢3向前进1,逢2原位改为-1并向前进1
*/
for (i = 0; i < 4; i++) {
if (warray[i] == 3) {
warray[i] = 0;
warray[i + 1]++;
} else if (warray[i] == 2) {
warray[i] = -1;
warray[i + 1]++;
}
}
/**
* printf
*/
boolean flag = true;
for (w = 81, i = 4; i >= 0; i--, w /= 3) {
if (warray[i] > 0 && !flag)
System.out.print("+");
if (warray[i] != 0) {
System.out.print("" + warray[i] * w);
flag = false;
}
}
System.out.println();
}
/**
* 求组合
*
* @param array
*/
public void group(int[] array) {
int length = array.length;
int temp[] = new int[2 * length];
int index = 0;
for (int i = 0; i < length; i++) {
temp[index++] = -array[i];
temp[index++] = array[i];
}
index = 0;
while (true) {
index++;
if (index == 2 * length)
break;
for (int i = 0; i < 2 * length; i++) {
int sum = ran(array);
if (sum >= 1 && sum <= 121) {
list.add(sum);
}
}
}
}
private int ran(int[] array) {
int sum = 0;
return sum;
}
public static void main(String[] args) throws Throwable {
Weight w = new Weight();
java.util.Scanner in = new java.util.Scanner(System.in);
int wei = in.nextInt();
w.nest(wei);
w.ternary(wei);
w.group(w.weight);
}
/**
* 思路四
*
* @param wei
*/
private void nest(int wei) {
int[] a, b, c, d, e;
a = b = c = d = e = new int[] { -1, 0, 1 };/* 指向同一heap内存 */
for (int ai : a) {
for (int bi : b) {
for (int ci : c) {
for (int di : d) {
for (int ei : e) {
if (wei == ai * 81 + bi * 27 + ci * 9 + di * 3 + ei
* 1)
System.out.println(ai * 81 + "+" + bi * 27
+ "+" + ci * 9 + "+" + di * 3 + "+"
+ ei * 1);
else
continue;
}
}
}
}
}
}
}