24点计算 --- 庞果
问题描述
24点游戏是一种使用扑克牌来进行的益智类游戏,游戏内容是:
- 从一副扑克牌中抽去大小王剩下52张,任意抽取4张牌
- 把牌面上的数(A代表1)运用加、减、乘、除和括号进行运算得出24。
- 每张牌都必须使用一次,但不能重复使用。
有些组合有不同种算法,例如要用2,4,6,12四张牌组合成24点,可以有如下几种组合方法:
- 2 + 4 + 6 + 12 = 24
- 4 × 6 ÷ 2 + 12 = 24
- 12 ÷ 4 × (6 + 2) = 24
当然,也有些组合算不出24,如1、1、1、1 和 6、7、8、8等组合。”
请完成函数can24,4张牌如果可以组成24点,返回1,不能则返回0。
友情提醒
注意以下这些组合:
- 1 1 1 10 不可以
- 6 6 6 6 可以
- 5 5 5 1 可以,即可以用分数,如(5-1/5)*5 = 24
- 1 1 1 11 可以
算法说明
使用的比较傻的递归算法
- 首先找出4个数的全排,然后一个一个全排去尝试
- 尝试的时候,从4个数中任意选两个组合四则运算,得出的结果和剩下的元素组成新数组,然后又任意选两个运算,直到数组为1看结果,输出。
算法很简单,玩一玩了。。。我感觉可以用动态规划来优化一下,懒得搞了。
#include <stdio.h> #include <string.h> #include <iostream> #include <string> #include <cmath> #include <vector> using namespace std; #define SWAP(t, a, b) do {t v=a; a=b; b=v;} while (0) #define OP(o,t,a,b) { t = a o b;} int _can24(vector<double> &numbers) { vector<double> tmp=numbers; //cout << tmp.size() << endl; if(numbers.size()==1) { if((numbers[0]-24<1e-8) && (numbers[0]-24>-1e-8)) { //cout << " Res :" << numbers[0] << endl; return 1; } else { //cout << " Res :" << numbers[0] << endl; return 0; } } for(int i=0;i<numbers.size();i++) { for(int j=i+1;j<numbers.size();j++) { if(i!=j) { //cout << " A: " << numbers[i] << " B: " << numbers[j] << endl; //tmp[i]=numbers[i]+numbers[j]; tmp.erase(tmp.begin()+j); OP(+,tmp[i],numbers[i],numbers[j]); if(_can24(tmp)==1) return 1; OP(-,tmp[i],numbers[i],numbers[j]); if(_can24(tmp)==1) return 1; OP(*,tmp[i],numbers[i],numbers[j]); if(_can24(tmp)==1) return 1; if(numbers[j]>1e-8 || numbers[j]<-1e-8) { OP(/,tmp[i],numbers[i],numbers[j]); if(_can24(tmp)==1) return 1; } tmp=numbers; } } } return 0; } int can24(int a, int b, int c, int d) { vector<double> numbers; numbers.push_back((double)a); numbers.push_back((double)b); numbers.push_back((double)c); numbers.push_back((double)d); //numbers.push_back((double)d); //__can24(numbers); vector<double> tmp=numbers; for(int i=0;i<numbers.size();i++) { SWAP(double,numbers[0],numbers[i]); for (int j = 1; j < numbers.size(); ++j ) { SWAP(double,numbers[1],numbers[j]); for(int p=2;p<numbers.size();p++) { SWAP(double,numbers[2],numbers[p]); tmp=numbers; if(_can24(numbers)==1) return 1; numbers=tmp; SWAP(double,numbers[2],numbers[p]); } SWAP(double,numbers[1],numbers[j]); } SWAP(double,numbers[0],numbers[i]); } return 0; } //start 提示:自动阅卷起始唯一标识,请勿删除或增加。 //可不完成,完成功能函数即可,给定主函数,是为方便你测试 int main(){ // cout << can24(8,7,8,8) << endl; cout<<can24(6,6,6,6)<<endl; cout<<can24(1,1,1,10)<<endl; //不可以 cout<<can24(5,5,5,1)<<endl; cout<<can24(1,1,1,11)<<endl; return 0; }