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

图个乐,可以用来计算问题,真的用来考试还是算了吧

全部评论

相关推荐

像好涩一样好学:这公司我也拿过 基本明确周六加班 工资还凑活 另外下次镜头往上点儿
点赞 评论 收藏
分享
评论
点赞
收藏
分享
牛客网
牛客企业服务