题解 | #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");
}
}
}
图个乐,可以用来计算问题,真的用来考试还是算了吧


查看11道真题和解析