1.问题描述:
用天平称重时,我们希望用尽可能少的砝码组合称出尽可能多的重量。
如果有无限个砝码,但它们的重量分别是1,3,9,27,81,……等3的指数幂
神奇之处在于用它们的组合可以称出任意整数重量(砝码允许放在左右两个盘中)。
本题目要求编程实现:对用户给定的重量,给出砝码组合方案,重量<1000000。
例如:
用户输入:
5
程序输出:
9-3-1
用户输入:
19
程序输出:
27-9+1
要求程序输出的组合总是大数在前小数在后。
可以假设用户的输入一定是一个大于0的整数
2.思路:
例如十进制数字17转换成三进制数字为122
先把字符串进行翻转,翻转的目的是为了在转换成字符数组之后进行更好的进位处理
翻转后字符串变成221,分别是低位像高位进行进位,第一个字符2向高位进一位,那么该位上应该要减去1,变成-131(17)
接下来进行第二个字符串3的处理,向上高位进一位应该是变成0,字符串变成-102(17)
进行第三个字符的处理向上进一位然后该位需要减去1,变成-10-11,最后的话把三进制位上的数字都改为-1和1
其中进行动态增加字符串可以使用ArrayList的add方法,将元素插入到指定位置add(int index, Integer element)
当插入的索引的位置处已经有值之后那么原来的索引及元素都会后移一位再把新的元素插入到这个指定的索引处
具体的代码如下:
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
//从控制台输入一个十进制整数
Scanner sc = new Scanner(System.in);
int N = sc.nextInt();
solve(N);
}private static void solve(int n) {
//把n转换成三进制而且翻转字符串并且转换成字符数组
//翻转字符串的目的是为了更好的进行进位的操作
final String str = Integer.toString(n,3);
List<Integer> list = new ArrayList<>();
char a[] = new StringBuilder(str).reverse().toString().toCharArray();
for(int i = 0;i<a.length;i++){
if(a[i]=='2'){//全部都是往0这个索引处增加元素值那么这个相当于栈,先插入的元素排列在后面
list.add(0,-1);
if(i==a.length-1){
list.add(0, 1);
}
//a[i+1]++必须是当i不是在a.length-1的时候加上的,否则会导致数组越界
else{//这里特别要注意数组越界的问题,所以需要使用else的逻辑来处理
a[i+1]++;
}
//有可能加1之后某些位上的数字变成3
}else if(a[i]=='3'){
list.add(0, 0);
if(i==a.length-1){
list.add(0, 1);
}else{
a[i+1]++;
}
}
else{
list.add(0, a[i]-'0');
}
}
StringBuilder sb = new StringBuilder();
for(int i = 0;i<list.size();i++){
if(list.get(i)==1){
sb.append("+").append((int)Math.pow(3, list.size()-i-1));
}
if(list.get(i)==-1){
sb.append("-").append((int)Math.pow(3, list.size()-i-1));
}
}
System.out.println(sb.toString().substring(1));
}
}