24点游戏

来源:互联网 发布:淘宝网中老年连衣裙 编辑:程序博客网 时间:2024/06/17 11:25

参考链接:速算24点

上面的链接里的代码是不允许计算中出现小数,这也是题目的要求,所以,那个代码对于“5 5 5 1”这个组合是没法计算出正确结果的。

我把程序改为能计算"5 5 5 1"之类的需要出现小数的情况,以及能输出相应的表达式,这里只输出一种可能的表达式。

/*题目规定整个计算过程中都不能出现小数,所以下面的代码能过。但是对于5,5,5,1是不能得到正确结果的,原因在于这里用的是整型,需要使用double型。*//*#include <iostream>#include <vector>#include <algorithm>using namespace std;int isok=0;vector<int> vi(4,0);void calcute(int up,int now,int ct){    if(isok) return ;    if(ct==3){        //到这里时,up一定要是第一个运算符。        if(up-now==24 || up*now==24 || up+now==24)            isok=1;        if(now!=0 && up%now==0 && up/now==24)            isok=1;        return ;    }    calcute(up-now, vi[ct+1], ct+1);if(isok) return ;    calcute(up+now, vi[ct+1], ct+1);if(isok) return ;    calcute(up*now, vi[ct+1], ct+1);if(isok) return ;    if(now!=0 && up%now==0){        calcute(up/now, vi[ct+1], ct+1);        if(isok) return ;    }    calcute(up, vi[ct+1]-now, ct+1);if(isok) return ;    calcute(up, vi[ct+1]+now, ct+1);if(isok) return ;    calcute(up, vi[ct+1]*now, ct+1);if(isok) return ;    if(vi[ct+1]!=0 && now%vi[ct+1]==0){        calcute(up, now/vi[ct+1], ct+1);        if(isok) return ;    }}int main(){    while(1){        string s;        isok=0;        vi=vector<int>(4,0);        for(int i=0;i<4;i++){            if(cin>>s){//由于这里的语句,需要使用G++编译环境                if(s=="10") vi[i]=10;                else if(s=="A") vi[i]=1;                else if(s=="J") vi[i]=11;                else if(s=="Q") vi[i]=12;                else if(s=="K") vi[i]=13;                else vi[i]=s[0]-'0';            }            else return 0;        }        sort(vi.begin(),vi.end());//必须要有这个,因为next_permutation是基于数组当前的排列给出下一个排列的,直到最大的排列(元素呈现非递增)为止。        do{            calcute(vi[0],vi[1],1);        }while(next_permutation(vi.begin(),vi.end()) && isok==0);        if(isok) cout<<"Yes"<<endl;        else cout<<"No"<<endl;    }    return 0;}*//*//这个可以计算double型的。#include <iostream>#include <vector>#include <algorithm>#include <cmath>using namespace std;int isok=0;vector<double> vi(4,0.);bool check(double val){    if(abs(val-24)<1e-6)        return true;    else return false;}void calcute(double up,double now,double ct){    if(isok) return ;    if(ct==3){        //到这里时,up一定要是第一个运算符。        if(check(up-now) || check(up*now) || check(up+now))            isok=1;        if(now!=0 && check(up/now))            isok=1;        return ;    }    calcute(up-now, vi[ct+1], ct+1);if(isok) return ;    calcute(up+now, vi[ct+1], ct+1);if(isok) return ;    calcute(up*now, vi[ct+1], ct+1);if(isok) return ;    if(now!=0){        calcute(up/now, vi[ct+1], ct+1);        if(isok) return ;    }    calcute(up, now-vi[ct+1], ct+1);if(isok) return ;    calcute(up, now+vi[ct+1], ct+1);if(isok) return ;    calcute(up, now*vi[ct+1], ct+1);if(isok) return ;    if(vi[ct+1]!=0){        calcute(up, now/vi[ct+1], ct+1);        if(isok) return ;    }}int main(){    while(1){        string s;        isok=0;        vi=vector<double>(4,0.);        for(int i=0;i<4;i++){            if(cin>>s){//由于这里的语句,需要使用G++编译环境                if(s=="10") vi[i]=10;                else if(s=="A") vi[i]=1;                else if(s=="J") vi[i]=11;                else if(s=="Q") vi[i]=12;                else if(s=="K") vi[i]=13;                else vi[i]=s[0]-'0';            }            else return 0;        }        sort(vi.begin(),vi.end());//必须要有这个,因为next_permutation是基于数组当前的排列给出下一个排列的,直到最大的排列(元素呈现非递增)为止。        do{            calcute(vi[0],vi[1],1);        }while(next_permutation(vi.begin(),vi.end()) && isok==0);        if(isok) cout<<"Yes"<<endl;        else cout<<"No"<<endl;    }    return 0;}*///这个可以输出表达式。#include <iostream>#include <vector>#include <algorithm>#include <cmath>#include <string>using namespace std;int isok=0;vector<double> vi(4,0.);vector<char> vires;bool check(double val){    if(abs(val-24)<1e-6)        return true;    else return false;}void calcute(double up,double now,double ct){    if(isok) return ;    if(ct==3){        vires.push_back('L');        if(isok==0 && check(up-now)){            isok=1;            vires.push_back('-');        }        if(isok==0 && check(up+now)){            isok=1;            vires.push_back('+');        }        if(isok==0 && check(up*now)){            isok=1;            vires.push_back('*');        }        if(isok==0 && now!=0 && check(up/now)){            isok=1;            vires.push_back('/');        }        if(isok==0) vires.pop_back();        return ;    }    vires.push_back('L');//表示当前符号是左结合    vires.push_back('-');    calcute(up-now, vi[ct+1], ct+1);if(isok) return ;    vires.pop_back();    vires.push_back('+');    calcute(up+now, vi[ct+1], ct+1);if(isok) return ;    vires.pop_back();    vires.push_back('*');    calcute(up*now, vi[ct+1], ct+1);if(isok) return ;    vires.pop_back();    if(now!=0){        vires.push_back('/');        calcute(up/now, vi[ct+1], ct+1);if(isok) return ;        vires.pop_back();    }    vires.pop_back();    vires.push_back('R');//表示当前符号是右结合    vires.push_back('-');    calcute(up, now-vi[ct+1], ct+1);if(isok) return ;    vires.pop_back();    vires.push_back('+');    calcute(up, now+vi[ct+1], ct+1);if(isok) return ;    vires.pop_back();    vires.push_back('*');    calcute(up, now*vi[ct+1], ct+1);if(isok) return ;    vires.pop_back();    if(vi[ct+1]!=0){        vires.push_back('/');        calcute(up, now/vi[ct+1], ct+1);if(isok) return ;        vires.pop_back();    }    vires.pop_back();}void rebuild(){    vector<int> weight;    for(auto ceh: vires){        if(ceh=='-' || ceh=='+') weight.push_back(0);        else weight.push_back(1);    }    vector<pair<string,int>> vs;    for(auto ieh: vi){        vs.push_back(pair<string,int>(to_string(int(ieh)),1));//每个原始的数为最高的优先级    }    for(int i=0;i<vires.size();i++){        string stp;        if(vires[i]=='R'){            if(vs[1].second<weight[i+1]){                vs[1].first="("+vs[1].first+")";                vs[1].second=1;//加完括号,已经是最高优先级了            }            if(vs[2].second<weight[i+1]){                vs[2].first="("+vs[2].first+")";                vs[2].second=1;            }            vs[1].first=vs[1].first+vires[i+1]+vs[2].first;            vs[1].second=weight[i+1];            vs.erase(vs.begin()+2);            i++;        }        if(vires[i]=='L'){            if(vs[0].second<weight[i+1]){                vs[0].first="("+vs[0].first+")";                vs[0].second=1;            }            if(vs[1].second<weight[i+1]){                vs[1].first="("+vs[1].first+")";                vs[1].second=1;            }            vs[0].first=vs[0].first+vires[i+1]+vs[1].first;            vs[0].second=weight[i+1];            vs.erase(vs.begin()+1);            i++;        }    }    cout<<vs[0].first<<endl;}int main(){    while(1){        string s;        isok=0;        vi=vector<double>(4,0.);        vires.clear();        for(int i=0;i<4;i++){            if(cin>>s){//由于这里的语句,需要使用G++编译环境                if(s=="10") vi[i]=10;                else if(s=="A") vi[i]=1;                else if(s=="J") vi[i]=11;                else if(s=="Q") vi[i]=12;                else if(s=="K") vi[i]=13;                else vi[i]=s[0]-'0';            }            else return 0;        }        sort(vi.begin(),vi.end());//必须要有这个,因为next_permutation是基于数组当前的排列给出下一个排列的,直到最大的排列(元素呈现非递增)为止。        do{            vires.clear();            calcute(vi[0],vi[1],1);//这里已经记录了各个数的顺序,在calcute中再记录一下操作符及结合顺序就可以了。            if(isok) break;//这里非常关键!!!        }while(next_permutation(vi.begin(),vi.end()) && isok==0);        if(isok){            rebuild();        }        if(isok) cout<<"Yes"<<endl;        else cout<<"No"<<endl;    }    return 0;}


原创粉丝点击