• 【NOI OpenJudge1789】算24(搜索)


    problem

    • 给定4个数,加减乘除4种运算以及括号把这4个数连接起来得到一个表达式。
    • 问是否存在一种方式使得得到的表达式的结果等于24。

    solution

    正常的中缀表达式枚举和计算难度都约等于0,麻烦的是括号的枚举和处理。
    这里只要求满足的结果,所以换一种方式拿掉括号——打乱顺序即可(括号的用处本质就是改变运算顺序),,

    • 做法就是通过枚举排列或者随机运算的方式去掉括号,剩余的运算符和数字丢到一起DFS即可。
    • 具体写法就是每次从剩余的数中随机取出两个数,并用加减乘除合并它们。
    • 小技巧:用排序代替数组来去掉不用位置写起来比较简单。(避免枚举的时候判断,也优化了效率。

    codes

    #include<iostream>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    const int uinf = -10000000;//过程值可以为负,所以要够小
    
    double a[5]; bool flag;
    double opv(double x, double y, int op){
        if(op==1)return x+y;
        if(op==2)return x-y;
        if(op==3)return x*y;
        if(op==4)return x/y;
    }
    void dfs(int x){
        sort(a+1,a+5);//用排序的方法把位置去掉
        if(flag)return ;
        if(x == 4){
            if(abs(a[4]-24)<0.001)flag = 1;//注意精度问题
            return ;
        }
    
        double b[5]; for(int i = 1; i <= 4; i++)b[i] = a[i];
        //在剩余的所有数里随便选2个
        for(int i = x; i <= 4; i++){
            for(int j = x; j <= 4; j++){
                if(i == j)continue;
                for(int k = 1; k <= 4; k++){//随便选一种运算
                    a[i] = opv(a[i],a[j],k);
                    a[j] = uinf;
                    dfs(x+1);
                    for(int i = 1; i <= 4; i++)a[i] = b[i];
                }
            }
        }
    }
    
    int main(){
        while(cin>>a[1]>>a[2]>>a[3]>>a[4] && a[1]){
            flag = 0;
            dfs(1);
            if(flag)cout<<"YES
    ";
            else cout<<"NO
    ";
        }
        return 0;
    }
    
    
  • 相关阅读:
    poj2186强连通分量
    poj1459SAP最大流模板题
    poj2391Floyd+二分+最大流
    curl上传下载入门
    Mysql存储过程
    小球旋转
    钟表单摆
    java小记 摘抄
    servlet的一些收集总结
    Javascript基础小结
  • 原文地址:https://www.cnblogs.com/gwj1314/p/10200056.html
Copyright © 2020-2023  润新知