• 算24点的算法,有输出


      主要使用了dfs的算法,比较麻烦的是如何去重,去重第一步可以用set来保存式子,然后再去多余的括号,然后在用另一个set去重。但是做到真正的去重还是比较麻烦,如果有好的建议的博友,可以私信。比如1*2*3*4与2*3*1*4其实是重复的2*(1+2)*4与2*4*(1+2)是重复的。

      代码如下:

      

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<string.h>
    #include<algorithm>
    #include<set>
    #include<iterator>
    using namespace std;
    int cmp(int a,int b){return a<=b;}
    void moveBrak(char* str);
    int m[4];
    //使用set主要是为了去重
    set<string> ss;
    
    void dfs(int sum,int cur,int i,string strSum,string strCur)
    {
        if(i==3)
        {
            char strTemp[100];
            if(sum+cur==24){
                sprintf(strTemp,"%s + %s = 24",strSum.c_str(),strCur.c_str());
                ss.insert(strTemp);
            }
            else if(sum - cur==24){
                sprintf(strTemp,"%s - %s = 24",strSum.c_str(),strCur.c_str());
                ss.insert(strTemp);
            }
            else if(sum * cur==24){
                sprintf(strTemp,"%s * %s = 24",strSum.c_str(),strCur.c_str());
                ss.insert(strTemp);
            }
            else if(cur && sum%cur==0 && sum / cur == 24){
                sprintf(strTemp,"%s / %s = 24",strSum.c_str(),strCur.c_str());
                ss.insert(strTemp);
            }
            return;
        }
        char strTemp[100];
        sprintf(strTemp,"%d",m[i+1]);
        dfs(sum,cur+m[i+1],i+1,strSum,"( "+strCur+" + "+strTemp+" )");
        dfs(sum,cur-m[i+1],i+1,strSum,"( "+strCur+" - "+strTemp+" )");
        dfs(sum,cur*m[i+1],i+1,strSum ,strCur+" * "+strTemp);
        if(m[i+1] && cur%m[i+1]==0)
            dfs(sum,cur/m[i+1],i+1,strSum,strCur+" / "+strTemp);
        dfs(sum+cur,m[i+1],i+1,"( "+strSum+" + "+strCur+" )",strTemp);
        dfs(sum-cur,m[i+1],i+1,"( "+strSum+" - "+strCur+" )",strTemp);
        dfs(sum*cur,m[i+1],i+1, strSum+" * "+strCur,strTemp);
        if(cur && sum%cur==0)
            dfs(sum/cur,m[i+1],i+1,strSum+" / "+strCur,strTemp);
    }
    
    int main()
    {
        while(~scanf("%d%d%d%d",&m[0],&m[1],&m[2],&m[3]))
        {
            ss.clear();
            sort(m,m+4,cmp);
            do
            {
                char strTemp[100];
                sprintf(strTemp,"%d",m[0]);
                string strSum = strTemp,strCur;
                sprintf(strTemp,"%d",m[1]);
                strCur = strTemp;
                dfs(m[0],m[1],1,strSum,strCur);
            }while(next_permutation(m,m+4));
    
            set<string>::iterator it = ss.begin();
            set<string> res;
    
            //去无效括号
            for(;it!=ss.end();it++)
            {
                char strTemp[100];
                strcpy(strTemp,it->c_str());
                moveBrak(strTemp);
                res.insert(strTemp);
            }
    
            int cnt = 0;
            it = res.begin();
            for(;it!=res.end();it++,++cnt)
                printf("%s
    ",it->c_str());
            if(cnt) printf("总共有%d个算式
    ",cnt);
            else    printf("没有符合条件的算式
    ");
        }
        return 0;
    }
    
    void moveBrak(char* str)
    {
        if(true) return;
        int len = strlen(str);
        //dev表示去掉的括号,left,right表示保留的括号
        char dev = '#',left = '$',right = '&';
        for(int i=0;i<len;++i)
        {
            if(str[i]==')')
            {
                int j = i-1;
                for(;j>=0;--j)
                    if(str[j]=='(')
                        break;
                //是否去掉括号
                bool bDev = false;
    
                if(i<len-2&&(str[i+2]=='+'||str[i+2]=='-'))
                    bDev = true;
                if(j>=2&&(str[j-2]=='+'))
                    bDev = true;
                else if(j>=2&&(str[j-2]=='-'||str[j-2]=='*'||str[j-2]=='/'))
                    bDev =  false;
                if(bDev)     str[i] = str[j] = dev;
                else         str[i] = right,str[j] = left;
            }
        }
        char strTemp[100];
        int k = 0;
        for(int i=0;i<len;++i)
        {
            if(str[i]==dev)
            {
                ++i;
                continue;
            }
            if(str[i]==left)
                strTemp[k++] = '(';
            else if(str[i]==right)
                strTemp[k++] = ')';
            else
                strTemp[k++] = str[i];
        }
        strTemp[k++] = '';
        memcpy(str,strTemp,k);
    }
  • 相关阅读:
    java 前端-BOM
    java web -tomcat
    java基础-递归
    java基础-正则表达式
    Hibernate从入门到精通(六)一对一双向关联映射
    Hibernate从入门到精通(五)一对一单向关联映射
    Hibernate从入门到精通(四)基本映射
    Hibernate从入门到精通(三)Hibernate配置文件
    Hibernate从入门到精通(二)Hibernate实例演示
    洛谷 P2701 [USACO5.3]巨大的牛棚Big Barn
  • 原文地址:https://www.cnblogs.com/jlyg/p/6758615.html
Copyright © 2020-2023  润新知