pongo题解之24点扑克牌游戏--C++实现

来源:互联网 发布:通用led显示屏软件 编辑:程序博客网 时间:2024/06/09 16:03

24点扑克牌游戏,就是用a,b,c,d(1<=a,b,c,d<=13 ,正整数)和运算符op1,op2,op3(+、-、×、/  注意:此处/不是整除)以及括号来拼凑出24,首先考虑枚举(蛮力)a,b,c,d的排列和op1,op2,op3的排列进行一一尝试,其中只需计算下面5个式子(将运算符看作中间结点,操作数看作叶子结点的树只有5种形状,其他式子可有运算符的不同排列转换为这5种之一):

(1)        ((a op1 b) op2 c) op3 d

(2)        (a op1 (b op2 c)) op3 d

(3)        (a op1 b) op2 (c op3 d)

(4)        a op1 ((b op2 c) op3 d)

(5)        a op1 (b op2 (c op3 d))

生成运算符的排列:考虑到三个减号时不成立,可以由{+++,--,***,///}中随意选择三个的组合再生成排列,共 A4,3+ A4,2 * A3,3/A2,2 +3=63中运算符排列,这个排列的生成可以通过静态变量只在第一调运函数时生成(当然这个可以打表)。

操作数排列(johnson-trotter算法):如果将a,b,c,d的排列全部生成出来再和运算符的排列通过双层循环一一尝试的话,效率不高,所以没得到a,b,c,d的一个新排列就尝试上面5个式子在运算符排列下是否成立。

i5+4G内存下:测试所有用例(1820个)有1362个成立,时间是1.7s左右

在pongo的hero在线测试0.5s左右

部分源代码如下:

#include<iostream>#include<vector>#include<stack>#include<algorithm>#include<set>#include<cmath>#include<fstream>#include<ctime>
const double pre=0.0001;const double N=24;std::set<std::vector<char>> resOp;//+-*/的所有排列void combination(size_t n,std::vector<char> & v,std::vector<std::vector<char>>&res){//组合Cm,n m=v.size()if(n<=0||n>v.size())return;std::vector<size_t> pos;std::vector<char>r;for(size_t i=0;i<n;i++){pos.push_back(i);r.push_back(v[i]);}while(true){res.push_back(r);while(pos[n-1]!=v.size()-1){pos[n-1]++;r[n-1]=v[pos[n-1]];res.push_back(r);}//whileint i=1;while(pos[n-1-i]==v.size()-1-i){if(i==n-1) return;i++;}//whilepos[n-1-i]++;r[n-1-i]=v[pos[n-1-i]];size_t k=1;for(size_t j=n-i;j<=n-1;j++){pos[j]=pos[n-1-i]+k;k++;r[j]=v[pos[j]];}}//while (true)}//combination()template<typename dType >void permutation(std::vector<dType> & v,std::set<std::vector<dType>>&resV){//由v生成排列if(v.size()<=0)return;std::vector<size_t> mid;//std::vector<int>direct;for(size_t i=0;i<v.size();i++){mid.push_back(i);direct.push_back(-1);}//forresV.insert(v);size_t moveEle=v.size()-1;size_t midP;size_t midMax;while(mid[moveEle]>0){//其实用不到midP=mid[moveEle];mid[moveEle]=mid[moveEle+direct[midP]];mid[moveEle+direct[midP]]=midP;char midV=v[moveEle];v[moveEle]=v[moveEle+direct[midP]];v[moveEle+direct[midP]]=midV;resV.insert(v);midMax=midP;for(std::vector<size_t>::const_iterator cit=mid.begin();cit!=mid.end();cit++){if(*cit>midP){direct[*cit]*=-1;if(direct[*cit]==1&&cit+1!=mid.end()||direct[*cit]==-1&&cit!=mid.begin()){if(*cit>*(cit+direct[*cit])&&*cit>midMax){midMax=*cit;moveEle=cit-mid.begin();}//if}//if}//if}//forif(midMax==midP){size_t i=midP;for(i=midP;i>0;i--){std::vector<size_t>::iterator it=std::find(mid.begin(),mid.end(),i);if(direct[i]==1&&it+1!=mid.end()||direct[i]==-1&&it!=mid.begin()){if(i>*(it+direct[i])){moveEle=it-mid.begin();break;}//}//}//forif(i==0) break;}//if}//while}//permutationinline double comp(double a,double b,char op){if('+'==op)return a+b;if('-'==op)return a-b;if('*'==op)return a*b;else if('/'==op)return a/b;else exit(1);}inline bool op1(int a,int b,int c,int d,char op1,char op2,char op3){//1if(std::fabs(comp(comp(comp(a,b,op1),c,op2),d,op3)-N)<=pre) return true;else return false;}inline bool op2(int a,int b,int c,int d,char op1,char op2,char op3){//2if(std::fabs(comp(comp(a,comp(b,c,op2),op1),d,op3)-N)<=pre) return true;else return false;}inline bool op3(int a,int b,int c,int d,char op1,char op2,char op3){//3if(std::fabs(comp(comp(a,b,op1),comp(c,d,op3),op2)-N)<=pre) return true;else return false;}inline bool op4(int a,int b,int c,int d,char op1,char op2,char op3){//4if(std::fabs(comp(a,comp(comp(b,c,op2),d,op3),op1)-N)<=pre) return true;else return false;}inline bool op5(int a,int b,int c,int d,char op1,char op2,char op3){//5if(std::fabs(comp(a,comp(b,comp(c,d,op3),op2),op1)-N)<=pre) return true;else return false;}void compOp(){std::vector<char> v;std::vector<std::vector<char>> res;v.push_back('+');v.push_back('+');v.push_back('-');v.push_back('-');v.push_back('*');v.push_back('*');v.push_back('/');v.push_back('/');v.push_back('/');combination(3,v,res);//C9,3for(std::vector<std::vector<char>>::iterator cit=res.begin();cit!=res.end();cit++)permutation(*cit,resOp);}int can24(int a,int b, int c,int d){//1=<a,b,c,d<=13//static bool firstTime=true; int midVal =a+b+c+d;if(midVal==N){//std::cout<<a<<"+"<<b<<"+"<<c<<"+"<<d<<std::endl;return 1;}midVal=a*b*c*d;if(midVal==N){//std::cout<<a<<"*"<<b<<"*"<<c<<"*"<<d<<std::endl;return 1;}/*if(firstTime){compOp();firstTime=false;}*/int flag=0;char ops [][3]={{'*','*','+'},{'*','*','-'},{'*','*','/'},{'*','+','*'},{'*','+','+'},{'*','+','-'},{'*','+','/'},{'*','-','*'},{'*','-','+'},{'*','-','-'},{'*','-','/'},{'*','/','*'},{'*','/','+'},{'*','/','-'},{'*','/','/'},{'+','*','*'},{'+','*','+'},{'+','*','-'},{'+','*','/'},{'+','+','*'},{'+','+','-'},{'+','+','/'},{'+','-','*'},{'+','-','+'},{'+','-','-'},{'+','-','/'},{'+','/','*'},{'+','/','+'},{'+','/','-'},{'+','/','/'},{'-','*','*'},{'-','*','+'},{'-','*','-'},{'-','*','/'},{'-','+','*'},{'-','+','+'},{'-','+','-'},{'-','+','/'},{'-','-','*'},{'-','-','+'},{'-','-','/'},{'-','/','*'},{'-','/','+'},{'-','/','-'},{'-','/','/'},{'/','*','*'},{'/','*','+'},{'/','*','-'},{'/','*','/'},{'/','+','*'},{'/','+','+'},{'/','+','-'},{'/','+','/'},{'/','-','*'},{'/','-','+'},{'/','-','-'},{'/','-','/'},{'/','/','*'},{'/','/','+'},{'/','/','-'},{'/','/','/'}};std::vector<int> vData;vData.push_back(a);vData.push_back(b);vData.push_back(c);vData.push_back(d);std::set<std::vector<int>> resData;//permutation(vData,resData);std::vector<size_t> mid;//std::vector<int>direct;for(size_t i=0;i<vData.size();i++){mid.push_back(i);direct.push_back(-1);}//for//resPos.push_back(mid);resData.insert(vData);std::vector<int>::iterator abcdIt=vData.begin();a=*abcdIt;abcdIt++;b=*abcdIt;abcdIt++;c=*abcdIt;abcdIt++;d=*abcdIt;for(int opi=0;opi<=60;opi++){if(op1(a,b,c,d,ops [opi][0],ops [opi][1],ops [opi][2])){///std::cout<<"method 1:"<<std::ends;//std::cout<<"(("<<(*citj)[0]<<(*cit)[0]<<(*citj)[1]<<")"<<(*cit)[1]<<(*citj)[2]<<")"<<(*cit)[2]<<(*citj)[3]<<std::endl;flag=1;return flag;}//if1if(op2(a,b,c,d,ops [opi][0],ops [opi][1],ops [opi][2])){///std::cout<<"method 2:"<<std::ends;//std::cout<<"("<<(*citj)[0]<<(*cit)[0]<<"("<<(*citj)[1]<<(*cit)[1]<<(*citj)[2]<<")"<<")"<<(*cit)[2]<<(*citj)[3]<<std::endl;flag=1;return flag;}//if2if(op3(a,b,c,d,ops [opi][0],ops [opi][1],ops [opi][2])){///std::cout<<"method 3:"<<std::ends;//std::cout<<"("<<(*citj)[0]<<(*cit)[0]<<(*citj)[1] <<")"<<(*cit)[1]<<"("<<(*citj)[2]<<(*cit)[2]<<(*citj)[3]<<")"<<std::endl;flag=1;return flag;}//if3if(op4(a,b,c,d,ops [opi][0],ops [opi][1],ops [opi][2])){///std::cout<<"method 4:"<<std::ends;//std::cout<<(*citj)[0]<<(*cit)[0]<<"("<<"("<<(*citj)[1]<<(*cit)[1]<<(*citj)[2]<<")"<<(*cit)[2]<<(*citj)[3]<<")"<<std::endl;flag=1;return flag;}//if4if(op5(a,b,c,d,ops [opi][0],ops [opi][1],ops [opi][2])){///std::cout<<"method 5:"<<std::ends;//std::cout<<(*citj)[0]<<(*cit)[0]<<"("<<(*citj)[1] <<(*cit)[1]<<"("<<(*citj)[2]<<(*cit)[2]<<(*citj)[3]<<")"<<")"<<std::endl;flag=1;return flag;}//if5}//for(int opi=0;opi<=60;opi++)size_t moveEle=vData.size()-1;size_t midP;size_t midMax;while(mid[moveEle]>0){midP=mid[moveEle];mid[moveEle]=mid[moveEle+direct[midP]];mid[moveEle+direct[midP]]=midP;//resPos.push_back(mid);char midV=vData[moveEle];vData[moveEle]=vData[moveEle+direct[midP]];vData[moveEle+direct[midP]]=midV;if(resData.find(vData)==resData.end()){abcdIt=vData.begin();a=*abcdIt;abcdIt++;b=*abcdIt;abcdIt++;c=*abcdIt;abcdIt++;d=*abcdIt;for(int opi=0;opi<=60;opi++){if(op1(a,b,c,d,ops [opi][0],ops [opi][1],ops [opi][2])){///std::cout<<"method 1:"<<std::ends;//std::cout<<"(("<<(*citj)[0]<<(*cit)[0]<<(*citj)[1]<<")"<<(*cit)[1]<<(*citj)[2]<<")"<<(*cit)[2]<<(*citj)[3]<<std::endl;flag=1;return flag;}//if1if(op2(a,b,c,d,ops [opi][0],ops [opi][1],ops [opi][2])){///std::cout<<"method 2:"<<std::ends;//std::cout<<"("<<(*citj)[0]<<(*cit)[0]<<"("<<(*citj)[1]<<(*cit)[1]<<(*citj)[2]<<")"<<")"<<(*cit)[2]<<(*citj)[3]<<std::endl;flag=1;return flag;}//if2if(op3(a,b,c,d,ops [opi][0],ops [opi][1],ops [opi][2])){///std::cout<<"method 3:"<<std::ends;//std::cout<<"("<<(*citj)[0]<<(*cit)[0]<<(*citj)[1] <<")"<<(*cit)[1]<<"("<<(*citj)[2]<<(*cit)[2]<<(*citj)[3]<<")"<<std::endl;flag=1;return flag;}//if3if(op4(a,b,c,d,ops [opi][0],ops [opi][1],ops [opi][2])){///std::cout<<"method 4:"<<std::ends;//std::cout<<(*citj)[0]<<(*cit)[0]<<"("<<"("<<(*citj)[1]<<(*cit)[1]<<(*citj)[2]<<")"<<(*cit)[2]<<(*citj)[3]<<")"<<std::endl;flag=1;return flag;}//if4if(op5(a,b,c,d,ops [opi][0],ops [opi][1],ops [opi][2])){///std::cout<<"method 5:"<<std::ends;//std::cout<<(*citj)[0]<<(*cit)[0]<<"("<<(*citj)[1] <<(*cit)[1]<<"("<<(*citj)[2]<<(*cit)[2]<<(*citj)[3]<<")"<<")"<<std::endl;flag=1;return flag;}//if5}//for(int opi=0;opi<=60;opi++)resData.insert(vData);}/////midMax=midP;for(std::vector<size_t>::const_iterator cit=mid.begin();cit!=mid.end();cit++){if(*cit>midP){direct[*cit]*=-1;if(direct[*cit]==1&&cit+1!=mid.end()||direct[*cit]==-1&&cit!=mid.begin()){if(*cit>*(cit+direct[*cit])&&*cit>midMax){midMax=*cit;moveEle=cit-mid.begin();}//if}//if}//if}//forif(midMax==midP){size_t i=midP;for(i=midP;i>0;i--){std::vector<size_t>::iterator it=std::find(mid.begin(),mid.end(),i);if(direct[i]==1&&it+1!=mid.end()||direct[i]==-1&&it!=mid.begin()){if(i>*(it+direct[i])){moveEle=it-mid.begin();break;}//}//}//forif(i==0) break;}//if}//whilereturn flag;}//can24()