24 点游戏
//a ,b,c,d 分别是4张牌的点数,result 保存表达式
bool To24Point(int a,int b int c,int d,string &result)
学了二叉树遍历的都知道,后续遍历可以消除表达式的符号。
因此24点最后的表达式就是 a b c d op1 op2 op3
据此 就是求 abcd op1 op2 op3 的 组合排列个数
a b c d 排列数为 P(4,4)=4x3x2x1 op1 op2 op3 的排列数为 4x4x4
所以有 24*4*4*4 = 1536 种,那么枚举一遍就可求了。
以下为代码
#include <stdio.h> #include <vector> #include <iostream> using namespace std; #define ADD_OP '+' #define MINUS_OP '-' #define MUL_OP '*' #define DIV_OP '/' static char s_operator_array[4]= { ADD_OP,MINUS_OP,MUL_OP,DIV_OP }; //计算表达式的值 //vecNum --- 保存操作数 //vecOp ---保存操作符 //result --- 保存结果,都加了括号 float CaculateExp(vector<int> & vecNum,vector<char> & vecOp,string &result) { int n = 0; vector<float> v ; for(int i=0; i<4; i++) { v.push_back((float)vecNum[i]); } vector<char> op = vecOp; float c; while(op.size()) { float a = *(v.begin()+v.size()-2); float b = *(v.begin()+v.size()-1); char chOp = *(op.begin()+op.size()-1); char buff[256]= {}; switch(chOp) { case ADD_OP: c = a+b; break; case MINUS_OP: c = a-b; break; case MUL_OP: c = a*b; break; case DIV_OP: if(b==0) { return 0; } c = a/b; break; } if(n==0) { sprintf(buff,"(%d%c%d)",(int)a,chOp,(int)b); result=buff; } else { sprintf(buff,"(%d%c%s)",(int)a,chOp,result.c_str()); result=buff; } n++; v.pop_back(); v.pop_back(); op.pop_back(); v.push_back(c); } return c; } //使用in 填充 vec ,填充的元素都是in的索引 void FullNumberVector(const vector<int> &in,vector<int>&vec,int index_1,int index_2,int index_3,int index_4) { vec.push_back(in[index_1]); vec.push_back(in[index_2]); vec.push_back(in[index_3]); vec.push_back(in[index_4]); } //使用n1 n2 n3 n4 填充 vec void FullNumberVector(vector<int>&vec,int n1,int n2,int n3,int n4) { vec.push_back(n1);vec.push_back(n2);vec.push_back(n3);vec.push_back(n4); } //使用s_operator_array 中的元素填充,selected_index_1 ...均为其索引 void FullOpVector(vector<char> &vec,int selected_index_1,int selected_index_2,int selected_index_3) { vec.push_back(s_operator_array[selected_index_1]); vec.push_back(s_operator_array[selected_index_2]); vec.push_back(s_operator_array[selected_index_3]); } //凑24点 //a--- 第一个参数 //b--- //c--- //c--- //result --- 表达式传回 //true -- 可以为24 false - 不能 bool To24Point(int a,int b,int c,int d,string &result) { const int NUMBER_COUNT = 4; const int OP_COUNT = 4; vector<int> vec; FullNumberVector(vec,a,b,c,d); for(int i=0; i<NUMBER_COUNT; i++){ for(int j=0; j<NUMBER_COUNT; j++){ if(j==i) continue; for(int k=0; k<NUMBER_COUNT; k++){ if(k==i || k==j) continue; for(int h=0; h<NUMBER_COUNT; h++){ if(h==i || h==j || h==k ) continue; printf("(%d,%d,%d,%d)\n",i,j,k,h); for(int ii=0; ii<OP_COUNT; ii++){ for(int jj=0; jj<OP_COUNT; jj++){ for(int kk=0; kk<OP_COUNT; kk++){ vector<int> out; vector<char> vecOpOut; FullNumberVector(vec,out,i,j,k,h); FullOpVector(vecOpOut,ii,jj,kk); string rs; float f=CaculateExp(out,vecOpOut,rs); if((int)(f+0.1)==24){ result = rs; return true; } } } } } } } } return false; } int main() { string result; int a,b,c,d; cout << "Please input 4 number:" << endl; cin >> a >> b >> c >> d; bool bb = To24Point(a,b,c,d,result); cout << "result = " << bb << " exp = " << result << endl; }