题解 | #24点游戏算法#人类大脑思考方式-逐个破解法
24点游戏算法
https://www.nowcoder.com/practice/fbc417f314f745b1978fc751a54ac8cb
使用的是逐个破解的方法,就是找出所有的数字的排列与符号的排列笛卡尔一下,逐个计算,得出24就break并输出结果true,遍历完还未得到24就输出false
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Scanner;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
public static void main(String[] args) {
Main me = new Main();
Scanner in = new Scanner(System.in);
// 注意 hasNext 和 hasNextLine 的区别
while (in.hasNextInt()) { // 注意 while 处理多个 case
int n0 = in.nextInt();
int n1 = in.nextInt();
int n2 = in.nextInt();
int n3 = in.nextInt();
LinkedList<Integer> lli = new LinkedList<>();
lli.add(n0);
lli.add(n1);
lli.add(n2);
lli.add(n3);
//alllist(arr)方法是自己写的对数组进行进行全排列的方法
HashSet<LinkedList<Integer>> hsl = me.alllist(lli);
Iterator<LinkedList<Integer>> hsli = hsl.iterator();
double res = 0;//因为题目说了除法是实数运算不是整除,所以结果得用double型存放
while (hsli.hasNext()) {//对四个数字的所有排列进行逐个循环计算
LinkedList<Integer> temp = hsli.next();
double a = temp.get(0);
double b = temp.get(1);
double c = temp.get(2);
double d = temp.get(3);
//如下三层循环代表a b c d的三个可以放运算符的空隙,每一层的0,1,2,3分别代表+,-,*,/四种运算符,通过这三层循环遍历找到所有的运算符排列
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
for (int k = 0; k < 4; k++) {
//此时的i,j,k分别代表三个位置上要放的运算符aibjckd;
//运算符和abcd确定后,接下来就是运算顺序的问题(这个其实就是加括号),那么一共有ijk,ikj,jik,jki,kji,kij 6种,因为abcd的顺序是确定了的,所以kij其实不存在,等同于ikj,所以最后是5种。
double res1 = me.twonumseval(me.twonumseval(me.twonumseval(a, b, i), c, j), d,
k);//i->j->k,((ab)c)d
double res2 = me.twonumseval(me.twonumseval(a, b, i), me.twonumseval(c, d, k),
j);//i->k->j和k->i->j,(ab)(cd)
double res3 = me.twonumseval(me.twonumseval(a, me.twonumseval(b, c, j), i ), d,
k);//j->i->k,(a(bc))d
double res4 = me.twonumseval(a, me.twonumseval(me.twonumseval(b, c, j), d, k ),
i );//j->k->i
double res5 = me.twonumseval(a, me.twonumseval(b, me.twonumseval(c, d, k), j),
i);//k->j->i
if (res1 == 24 || res2 == 24 || res3 == 24 || res4 == 24 || res5 == 24) {
res = 24;
break;
}
}
if (res == 24) {
break;
}
}
if (res == 24) {
break;
}
}
if (res == 24) {
System.out.println(true);
break;
}
}
if (res != 24) {
System.out.println(false);
}
}
}
double twonumseval(double num1, double num2, int sign) {
double res = 99999;
switch (sign) {
case 0:
res = num1 + num2;
break;
case 1:
res = num1 - num2;
break;
case 2:
res = num1 * num2;
break;
case 3:
if (num2 != 0) {
res = (num1 * 100) / num2 * 0.01;
}
break;
}
return res;
}
//递归方法求数组全排列
HashSet<LinkedList<Integer>> alllist(LinkedList<Integer> arr) {
int l = arr.size();
HashSet<LinkedList<Integer>> out = new HashSet<>();
if (l == 1) {
out.add(arr);
return out;
} else {
int templast = arr.pollLast();
HashSet<LinkedList<Integer>> temp = alllist(arr);
temp.forEach(n-> {
int ln = n.size();
for (int i = 0; i <= ln; i++) {
n.add(i, templast);
out.add(new LinkedList<>(n));
n.remove(i);
}
});
return out;
}
}
}
查看10道真题和解析