关注微信公众号瓠悠笑软件部落
用1,2,3,4,5,6,7,8,9这9个数字组成一个九位数(每个数字恰好用一次)。使得它的前三位,中三位,后三位的比值是3:2:1,求所有满足条件的数?
刚毕业那会的一道题,转眼8年过去了,没想到有3325人访问,抱歉,误导大家了。重新想了一下解法。肯定不是最好的办法,希望大家指导。
题目分析:
- 既然这个数的前三位,中三位,后三位的比值是3:2:1. 不妨设置1是m。 那这三个数是 3m:2m:1m.
- 打算用遍历去做这个事情,那就要缩小循环的范围,所以要找到m的最大值和最小值。m肯定是一个三位数。并且是有三个不同数字组成的三位数。可以想到,987是这里面的最大值(m=987/3=329). 那m的最大值是329. 123可以作为m的最小值(还没有验证能不能满足条件3m:2m:1m)。
- 所以这个循环的开始是123,结束是329. 需要循环329-123+1=207次。
- 那么,每次循环要干什么呢。这个9位数有个显著的条件是每一位都是不同的数字。我只需要计算2m的数字组成是不是包含m里面的任意一个数字,如果有就continue。3m是不是包换 m 和 2m里面的数字,如果有就continue。如果没有,那么拼接这三个数,就是要找到的数字了。
Java代码实现:
import java.util.ArrayList;
import java.util.List;
public class FindNumber {
public static List<Integer> findTarget() {
List<Integer> findResult = new ArrayList<>(10);
List<Character> usedNum = new ArrayList<>(10);
for(int m=123; m<=329; m++) {
char[] mUsed = String.valueOf(m).toCharArray();
usedNum.add(mUsed[0]);
usedNum.add(mUsed[1]);
usedNum.add(mUsed[2]);
int dm = m*2;
char[] dmUsed = String.valueOf(dm).toCharArray();
// if contain any number. continue next loop.
if(usedNum.contains(dmUsed[0]) || usedNum.contains(dmUsed[1]) || usedNum.contains(dmUsed[2])) {
usedNum.clear();
continue;
}
// if not contain. add number to set for 3m justify.
usedNum.add(dmUsed[0]);
usedNum.add(dmUsed[1]);
usedNum.add(dmUsed[2]);
int tm = m*3;
char[] tmUsed = String.valueOf(tm).toCharArray();
// if contain any number. continue next loop.
if(usedNum.contains(tmUsed[0]) || usedNum.contains(tmUsed[1]) || usedNum.contains(tmUsed[2])) {
usedNum.clear();
continue;
}
findResult.add(tm * 1000000 + dm*1000 + m);
}
return findResult;
}
public static void main(String args[]) {
List<Integer> findResult = FindNumber.findTarget();
System.out.println(findResult.toString());
}
}