前言
大家小时候可能也玩过“组合车牌号里的 4 个数字最终得到 10”的游戏。组合的方法是在各个数字之间插入四则运算的运算符组成算式,然后计算算式的结果(某些数位之间可以没有运算符,但最少要插入 1 个运算符)。
例 1234 → 1+2×3 - 4=3
9876 → 9×87+6=789
假设这里的条件是,组合算式的计算结果为“将原数字各个数位上的数逆序排列得到的数”,并且算式的运算按照四则运算的顺序进行(先乘除,后加减)。
那么位于 100~999,符合条件的有以下几种情况。
351 → 3×51=153
621 → 6×21=126
886 → 8×86=688
问题
求位于 1000~9999,满足上述条件的数。
代码
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
public class Q2 {
public static void main(String[] args) {
String[] op = new String[] { "+", "-","*", "/","" };
ScriptEngine engine = new ScriptEngineManager().getEngineByName("js");
for (int i = 1000; i < 10000; i++) {
String num = String.valueOf(i);
for (int j = 0; j < op.length; j++) {
for (int p = 0; p < op.length; p++) {
for (int k = 0; k < op.length; k++) {
if (op[j] == "" && op[p] == "" && op[k] == "") {
continue;
}
char c0 = num.charAt(0);
char c1 = num.charAt(1);
char c2 = num.charAt(2);
char c3 = num.charAt(3);
// 不能 /0
if ((c2 == '0' && op[j].equals("/")) || (c1 == '0' && op[p].equals("/"))
|| (c0 == '0' && op[k].equals("/"))) {
continue;
}
// 0不能开头,因以0开头是8进制表示
if ((c3 == '0' && op[j] == "") || (c2 == '0' && op[p] == "") || (c1 == '0' && op[k] == "")
|| (c2 == '0' && c3 == '0' && op[k] == "")) {
continue;
}
String string = c3 + op[j] + c2 + op[p] + c1 + op[k] + c0;
try {
if (String.valueOf(engine.eval(string)).equals(String.valueOf(i))) {
System.out.println("" + i + "=" + string);
}
} catch (Exception e) {
//System.err.println(string);
e.printStackTrace();
//continue;
}
}
}
}
}
}
}
注意的点有:需要对 0 进行特别处理。例如在java 中,“以 0 开头的数”会被当作八进制数来处理,因此必须排除以0 开头的数。此外,也需要排除除数为 0 的情况
答案
1395=5931
思路改进
用“+”时,最大的值只有999+9=1008。逆序排列不可能得到原始值。当然,用“-”或’ \ ‘也不可能,只会使数变小,4位组合中最大的只用999,999做’ -’ 或 ’ \ '不能凑出四位。
所以将操作符数组改为
String[] op = new String[] { "*","" };