题解 | #24点游戏算法# 排列组合+括号枚举+四则运算
24点游戏算法
https://www.nowcoder.com/practice/fbc417f314f745b1978fc751a54ac8cb
import java.util.Scanner; import java.util.ArrayList; import java.util.List; import java.util.Scanner; import java.util.Stack; public class Main { public static int slove(String s){ Stack<Integer> stack=new Stack<>(); int n=s.length(); char[] chs=s.toCharArray(); int index=0; //初始化符号为'+' char sign='+'; //记录数字 int number=0; for(int i=0;i<n;i++){ char ch=chs[i]; //当前字符是空格,跳过 if(ch==' ')continue; //当前字符是数字,拼数字 if(Character.isDigit(ch)){ number=number*10+ch-'0'; } //如果当前字符是小括号 if(ch=='('){ //移到小括号后一位字符 int j=i+1; //统计括号的数量 int count=1; while(count>0){ //遇到右括号,括号数-1 if(chs[j]==')')count--; //遇到左括号,括号数+1 if(chs[j]=='(')count++; j++; } //递归,解小括号中的表达式 number=slove(s.substring(i+1,j-1)); i=j-1; } //遇到符号,会去处理上一个符号,默认的数是0,符号是正,这样在一开始遇到正负号的时候就不怕了 if(!Character.isDigit(ch) || i==n-1){ //如果是'+',直接入栈 if(sign=='+'){ stack.push(number); } //如果是'-',数字取相反数在入栈 else if(sign=='-'){ stack.push(-1*number); } //如果是'*',弹出一个数字乘后放入栈 else if(sign=='*'){ stack.push(stack.pop()*number); } //如果是'/',弹出一个数字/后放入栈 else if(sign=='/'){ stack.push(stack.pop()/number); } //更新符号 sign=ch; //刷新数字 number=0; } } //栈中数字求和得到结果 int ans=0; while(!stack.isEmpty()){ ans+=stack.pop(); } return ans; } /** * 加符号 * (1+1)+1+1 * (1+1+1)+1 * 1+(1+1)+1 * 1+(1+1+1) * 1+1+(1+1) * (1+1)+(1+1) * 其实应该还有嵌套括号的情况发生,但是我觉得嵌套的式子应该也可以化简为不嵌套的,maybe... */ private static boolean fun1(List<String> list,int target){ char[] op={'+','-','*','/'}; int result; for(int i=0;i<3;i++){ for(int j=0;j<3;j++){ for(int k=0;k<3;k++){ result=slove('('+list.get(0)+op[i]+list.get(1)+')'+op[j]+list.get(2)+op[k]+list.get(3)); if(result==target) return true; result=slove('('+list.get(0)+op[i]+list.get(1)+op[j]+list.get(2)+')'+op[k]+list.get(3)); if(result==target) return true; result=slove(list.get(0)+op[i]+'('+list.get(1)+op[j]+list.get(2)+')'+op[k]+list.get(3)); if(result==target) return true; result=slove(list.get(0)+op[i]+'('+list.get(1)+op[j]+list.get(2)+op[k]+list.get(3)+')'); if(result==target) return true; result=slove(list.get(0)+op[i]+list.get(1)+op[j]+'('+list.get(2)+op[k]+list.get(3)+')'); if(result==target) return true; result=slove('('+list.get(0)+op[i]+list.get(1)+')'+op[j]+'('+list.get(2)+op[k]+list.get(3)+')'); if(result==target) return true; } } } return false; } /** * 四个数排列组合 */ static int[] flag=new int[4]; private static boolean permu(String[] strs, List<String> list, int num,int target){ if(num==4){ return fun1(list,target); } int i=0; for(i=0;i<4;i++){ if(flag[i]!=0){ continue; } flag[i]=1; list.add(strs[i]); if(permu(strs,list,num+1,target)) return true; flag[i]=0; list.remove(num); } return false; } public static void main(String[] args) { Scanner s=new Scanner(System.in); int target=24; if(permu(s.nextLine().split(" "),new ArrayList<String>(),0,target)){ System.out.println("true"); }else{ System.out.println("false"); } } }
图个乐,可以用来计算问题,真的用来考试还是算了吧