题解 | #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; } } }