前言
一前公司同事把此题放在群里,求大家帮忙解答。
因为没有其他条件和说明。我的第一印象就是:方格里应该填1~9整数中剩下的1~8,且不能重复。于是拿着笔进行了一通计算。。。后来发现无解。
接着,就想里面的算术运算符(+、-、×、÷),不按优先级,直接按先后顺序来计算,如:a - b × c,当做(a - b) × c 来运算。最后得到如下结果:
5 8 9
7 6 4
3 2 1
为了锻炼下自己的算法能力,后来用Java写了份代码来测试:
public static void main(String[] args) {
nineBlockBox();
}
private static void nineBlockBox() {
List<int[]> result = compute();
printf("打印结果:\n");
for (int i = 0; i < result.size(); i++) {
printf("第%d组结果:\n", i+1);
int count = 0;
for (int a : result.get(i)) {
printf(a + "\t");
if (++count == 3) {
printf("\n");
count = 0;
}
}
}
}
private static List<int[]> compute() {
// 九宫格位置:
// 0 1 2
// 3 4 5
// 6 7 8
// 条件
// ① (nb[0] + nb[1]) - 9 = 4
// ② (nb[3] - nb[4]) * nb[5] = 4
// ③ (nb[6] + nb[7]) - nb[8] = 4
// ④ (nb[0] + nb[3]) / nb[6] = 4
// ⑤ (nb[1] - nb[4]) * nb[7] = 4
// ⑥ ( 9 - nb[5]) - nb[8] = 4
List<int[]> list = new ArrayList<>();
int[] nb = new int[9];
for (int i = 1; i <= 9; i++) {
// 初始化数值
initArr(nb);
if (!isNumValid(nb, i)) {
continue;
}
nb[0] = i;
// ① (nb[0] + nb[1]) - 9 = 4
int temp = 4 + 9 - nb[0];
if (!isNumValid(nb, temp)) {
nb[0] = 0;
continue;
}
nb[1] = temp;
for (int j = 1; j <= 9; j++) {
if (!isNumValid(nb, j)) {
continue;
}
nb[5] = j;
// ⑥ ( 9 - nb[5]) - nb[8] = 4
temp = 9 - nb[5] - 4;
if (!isNumValid(nb, temp)) {
nb[5] = 0;
continue;
}
nb[8] = temp;
for (int k = 1; k <= 9; k++) {
if (!isNumValid(nb, k)) {
continue;
}
nb[3] = k;
// ② (nb[3] - nb[4]) * nb[5] = 4
// 4 = 1 * 4 = 2 * 2
temp = nb[3] - 4 / nb[5];
if (!isNumValid(nb, temp)) {
nb[3] = 0;
continue;
}
nb[4] = temp;
for (int m = 1; m <= 9; m++) {
if (!isNumValid(nb, m)) {
continue;
}
nb[6] = m;
// ③ (nb[6] + nb[7]) - nb[8] = 4
temp = 4 + nb[8] - nb[6];
if (!isNumValid(nb, temp)) {
nb[6] = 0;
continue;
}
nb[7] = temp;
// ④ (nb[0] + nb[3]) / nb[6] = 4
// ⑤ (nb[1] - nb[4]) * nb[7] = 4
if (((nb[0] + nb[3]) / nb[6] == 4) && ((nb[1] - nb[4]) * nb[7] == 4)) {
int[] result = new int[nb.length];
System.arraycopy(nb, 0, result, 0, nb.length);
list.add(result);
}
nb[6] = nb[7] = 0;
}
nb[3] = nb[4] = 0;
}
nb[5] = nb[8] = 0;
}
}
return list;
}
private static void initArr(int[] arr) {
Arrays.fill(arr, 0);
arr[2] = 9;
}
private static boolean isNumValid(final int[] arr, final int num) {
if (num < 1 || num > 9) {
return false;
}
for (int a : arr) {
if (a == num) {
return false;
}
}
return true;
}
打印结果:
后来百度得知这是一道腾讯校招笔试题。
正题
题目:
用0~100的整数填入以下方格中,使填入后的运算结果,满足下图所示的条件。求出所有解。
个人解答过程:
把每一个条件进行,并把相关的条件进行整合分析,最后根据整合结果写代码。条件的分析在代码中(为了方便阅读理解,没有作优化,如i, j, k临时变量完全可以去掉)
private static List<int[]> compute_100() {
// 九宫格位置:
// 0 1 2
// 3 4 5
// 6 7 8
// 条件
// ① a[0] + a[1] - 9 = 4
// ② a[3] - a[4] * a[5] = 4
// ③ a[6] + a[7] - a[8] = 4
// ④ a[0] + a[3] / a[6] = 4
// ⑤ a[1] - a[4] * a[7] = 4
// ⑥ 9 - a[5] - a[8] = 4
/*
分析
①:a[0] + a[1] = 13 --> a[0]∈[0,13], a[1]∈[0,13] ......⑦
②:a[3] >= 4
④:a[0] <= 4, a[6] != 0 +⑦--> a[0]∈[0,4],a[1]∈[9,13] ......⑧
⑤:a[1] >= 4 +⑧--> (a[4] * a[7])∈[5,9],即:a[4]∈[1,9],a[7]∈[1,9]
⑥:a[5] + a[8] = 5 --> a[5]∈[0,5], a[8]∈[0,5]
*/
List<int[]> list = new ArrayList<>();
int[] a = new int[9];
a[2] = 9;
for (int i = 0; i <= 4; i++) {
a[0] = i;
a[1] = 13 - i; // ① a[0] + a[1] - 9 = 4
for (int j = 0; j <= 5; j++) {
a[5] = j;
a[8] = 5 - j; // ⑥ 9 - a[5] - a[8] = 4
for (int k = 1; k <= 9; k++) {
a[4] = k;
a[3] = 4 + a[4] * a[5]; // ② nb[3] - nb[4] * nb[5] = 4
float temp = (a[1] - 4) / a[4]; // ⑤ nb[1] - nb[4] * nb[7] = 4
// 去小数
if (a[1] - a[4] * temp != 4f) {
continue;
}
a[7] = (int)temp;
a[6] = 4 + a[8] - a[7]; // ③ nb[6] + nb[7] - nb[8] = 4
if (a[6] != 0) {
// 去小数
if (a[0] + a[3] * 1f / a[6] == 4f) { // ④ nb[0] + nb[3] / nb[6] = 4
int[] result = new int[a.length];
System.arraycopy(a, 0, result, 0, a.length);
list.add(result);
}
}
}
}
}
return list;
}
打印结果只有一组: