之前在面試試題一(排列組合)具體實現了24點游戲中涉及的排列組合,這里用c++具體實現24點游戲。。
24點的游戲規則是:給玩家4張牌,每張牌的面值在1到13之間,利用加減乘除使得結果為24,可以使用括號。。。
用遞歸簡單實現了下:(雖然規則是4個數是在1到13之間,但程序也可以輸入不在13之內的數字)
#include<iostream> #include<vector> #include<string> using namespace std; int tag[3]; //存放3個運算符的優先級,1表示+-,2表示* / /* 根據tag標記的優先級判斷是否加括號(從左向右計算),加輸出加括號的表達式返回false,不加返回true*/ bool isOk(string s) { int t = 0; int m, n; if (tag[0] == 1 && tag[1] == 1 && tag[2] == 2 || tag[0] == 2 && tag[1] == 1 && tag[2] == 2) { m = s.rfind("*"); n = s.rfind("/"); t = m >n ? m : n; string temp = "(" + s.substr(0, t) + ")" + s.substr(t)+" =24"; cout << temp<< endl; return false; } else if (tag[0] == 1 && tag[1] == 2) { string temp = "(" + s.substr(0, 3) + ")" + s.substr(3) + " =24"; cout <<temp<< endl; return false; } return true; } /***********************對排列好的組合進行計算(遞歸)*******************************/ /********表示當前有t個數參與計算 ;num為當前t個數的計算結果(值);當前的表達式*****/ void computer(int t, int num, string s, vector<int> &arr) { if (t == 4) { //這里是既不需要加括號而且結果為24輸出, //當結果為24時,看從左到右計算是否滿足計算優先級,利用is0k()函數加括號,在isOk函數中輸出。 if (num == 24 && isOk(s)) { cout << s << " =24 " << endl; } return; } if (t == 0) { computer(t + 1, num + arr[t], to_string(arr[0]), arr); return; } for (int i = 0; i < 4; i++) { if (i == 0) { tag[t - 1] = 1; computer(t + 1, num + arr[t], s + "+" + to_string(arr[t]),arr); } if (i == 1) { tag[t - 1] = 1; if (num - arr[t] > 0) { computer(t + 1, num - arr[t],s + "-" + to_string(arr[t]),arr); } //else //如果return時返回上次一層t-1情況,for循環后面的情況沒有考慮 //{ // return; //} } if (i == 2) { tag[t - 1] = 2; computer(t + 1, num * arr[t], s + "*" + to_string(arr[t]),arr); } if (i == 3) { tag[t - 1] = 2; if (num % arr[t] == 0) { computer(t + 1, num / arr[t], s + "/" + to_string(arr[t]),arr); } //else //{ // return; //} } } } void getOrder(size_t t, vector<int> &arr, int &cnt) //進行排列組合,t從0開始,cnt計算有多少排列方式 { if (t >= arr.size()) { computer(0, 0, "",arr); //每一次排列好組合,對排列好的4個數用不同的方法計算。 cnt++; return; } for (size_t i = t; i < arr.size(); i++) { if (i != t) swap(arr[i], arr[t]); getOrder(t + 1, arr, cnt); if (i != t) swap(arr[i], arr[t]); //表示交換之后再交換回來,要在原有的基礎上(a,b,c,d)進行交換 } } int main() //測試 { static int cnt = 0; vector<int> arr; //存放4個數字 cout << "**********************************24點游戲******************************" << endl; cout << "*******************請輸入4個數字,並且4個數字均要在1到13之間************" << endl; int a, b, c, d; cin >> a >> b >> c >> d; arr.push_back(a); arr.push_back(b); arr.push_back(c); arr.push_back(d); getOrder(0, arr, cnt); return 0; }
運行結果: