一:概述
“24点算法”的游戏内容如下:一副牌中抽去大小王剩下52张,其中J、Q、K分别相当于11、12、13,任意抽取4张牌(称牌组),用加、减、乘、除(可加括号)把牌面上的数算成24
二:算法
1. 穷举法(穷举所有可能,即四个数字(1-13),中间三个操作符的四种运算(加减乘除),五种运算组合,穷举出所有的可能进行计算)
#include <iostream>
using namespace std;
// 格式: num1 # num2 # num3 # num4
// | | | | | | |
// 数字1 操作符1 数字2 操作符2 数字3 操作符3 数字4
// 按照上面的格式,遍历所有的值可能,遍历所有的计算组合
// 精度范围,差的绝对值小于此值认为两个值相等
const float EPSINON = 0.0001;
// 四个数字(范围1 - 13)
int num1 = 0;
int num2 = 0;
int num3 = 0;
int num4 = 0;
// 三个运算符(范围1 - 4,依次表示加减乘除)
int opera1 = 0;
int opera2 = 0;
int opera3 = 0;
// 结果存储
float r1 = 0;
float r2 = 0;
float r3 = 0;
// 打印字符(下标1-4依次为加减乘除)
char c[5]={' ','+','-','*','/'};
// 计算(a ,b为两个数字,opera为运算符)
float Calculation(float a, int opera, float b)
{
switch (opera)
{
case 1: // 加
return a+b;
case 2: // 减
return a-b;
case 3: // 乘
return a*b;
case 4: // 除
return a/b;
}
}
// 判断是否是24
bool Is24(float value)
{
if ( (value-24 > -EPSINON) && (value-24 < EPSINON))
{
return true;
}
return false;
}
// 判断是否是0
bool Is0(float value)
{
if ( (value > -EPSINON) && (value < EPSINON))
{
return true;
}
return false;
}
void main()
{
// 结果序号
int number=0;
for (num1=1;num1<=13;num1++)// 数字1
{
for (opera1=1;opera1<=4;opera1++)// 运算符1
{
for (num2=1;num2<=13;num2++)// 数字2
{
for (opera2=1;opera2<=4;opera2++)// 运算符2
{
for (num3=1;num3<=13;num3++)// 数字3
{
for (opera3=1;opera3<=4;opera3++)// 运算符3
{
for (num4=1;num4<=13;num4++)// 数字4
{
// 组合顺序:((num1 opera1 num2) opera2 num3) opera3 num4
r1 = r2 = r3 = 0; // 计算前清零
r1 = Calculation((float)num1,opera1,(float)num2); // 计算 num1 和 num2 赋给r1
r2 = Calculation(r1,opera2,(float)num3); // 计算 r1 和 num3 赋给r2
r3 = Calculation(r2,opera3,(float)num4); // 计算 r2 和 num4 赋给r3
if (Is24(r3)) // 结果是24的打印
{
number++;
cout<<number<<" :"<<"(("<<num1<<c[opera1]<<num2<<")"<<c[opera2]<<
num3<<")"<<c[opera3]<<num4<<" = 24"<<endl;
}
// 组合顺序: (num1 opera1 num2) opera2 (num3 opera3 num4)
r1 = r2 = r3 = 0; // 计算前清零
r1 = Calculation((float)num1,opera1,(float)num2); // 计算 num1 和 num2 赋给r1
r2 = Calculation((float)num3,opera3,(float)num4); // 计算 num3 和 num4 赋给r2
if ( (opera2 == 4 && Is0(r2)) == false) // 计算 r1和 r2(当运算为除法并且r2为0时不计算)
{
r3 = Calculation(r1,opera2,r2);
}
if (Is24(r3)) // 结果是24的打印
{
number++;
cout<<number<<" :"<<"("<<num1<<c[opera1]<<num2<<")"<<c[opera2]<<"("<<
num3<<c[opera3]<<num4<<") = 24"<<endl;
}
// 组合顺序:(num1 opera1 (num2 opera2 num3)) opera3 num4
r1 = r2 = r3 = 0; // 计算前清零
r1 = Calculation((float)num2,opera2,(float)num3); // 计算 num2 和 num3 赋给r1
if ( (opera1 == 4 && Is0(r1)) == false) // 计算 num1 和 r1 赋给r2(当运算为除法并且r1为0时不计算)
{
r2 = Calculation(num1,opera1,r1);
}
r3 = Calculation(r2,opera3,(float)num4); // 计算 r2 和 num4 赋给r3
if (Is24(r3)) // 结果是24的打印
{
number++;
cout<<number<<" :"<<"("<<num1<<c[opera1]<<"("<<num2<<c[opera2]<<
num3<<"))"<<c[opera3]<<num4<<" = 24"<<endl;
}
// 组合顺序: num1 opera1 ((num2 opera2 num3) opera3 num4)
r1 = r2 = r3 = 0; // 计算前清零
r1 = Calculation((float)num2,opera2,(float)num3); // 计算 num2 和 num3 赋给r1
r2 = Calculation(r1,opera3,(float)num4); // 计算 r1 和 num4 赋给r2
if ((opera1 == 4 && Is0(r2)) == false) // 计算 num1 和 r2 赋给r3(当运算为除法并且r2为0时不计算)
{
r3 = Calculation((float)num1,opera1,r2);
}
if (Is24(r3)) // 结果是24的打印
{
number++;
cout<<number<<" :"<<num1<<c[opera1]<<"(("<<num2<<c[opera2]<<
num3<<")"<<c[opera3]<<num4<<") = 24"<<endl;
}
// 组合顺序: num1 opera1 (num2 opera2 (num3 opera3 num4))
r1 = r2 = r3 = 0; // 计算前清零
r1 = Calculation((float)num3,opera3,(float)num4); // 计算 num3 和 num4 赋给r1
if ( (opera2 == 4 && Is0(r1)) == false) // 计算 num2 和 r1 赋给r2(当运算为除法并且r1为0时不计算)
{
r2 = Calculation((float)num2,opera2,r1);
}
if ( (opera1 == 4 && Is0(r2)) == false) // 计算 num1 和 r2 赋给r3(当运算为除法并且r2为0时不计算)
{
r3 = Calculation((float)num1,opera1,r2);
}
if (Is24(r3))
{
number++;
cout<<number<<" :"<<num1<<c[opera1]<<"("<<num2<<c[opera2]<<"("<<
num3<<c[opera3]<<num4<<")) = 24"<<endl;
}
}
}
}
}
}
}
}
getchar();
}
2. 递归法