一、题目:24点游戏是经典的纸牌益智游戏。
从扑克中每次取出4张牌。使用加减乘除,第一个能得出24者为赢。(其中,J代表11,Q代表12,K代表13,A代表1),按照要求编程解决24点游戏。
基本要求: 随机生成4个代表扑克牌牌面的数字字母,程序自动列出所有可能算出24的表达式,用擅长的语言(C/C++/Java或其他均可)实现程序解决问题。
1.程序风格良好(使用自定义注释模板)
2.列出表达式无重复。
二、.源代码
#include<iostream>
#include<stdlib.h>
using namespace std;
class Dian
{
public:
int division(int p,int q);//除法
int judge(int a,int b,int c);//选择两者之间的关系
char print(int c);//输出符号
void menu();//界面显示
int ceshi(); //是否继续进行的判断
};
//除法
int Dian::division(int p,int q)
{
if(q==0){
cout<<"分母不能为0"<<endl;
}
if(p%q==0) return p/q;
else
return 100000;
}
//选择两者之间的关系
int Dian::judge(int a,int b,int c)
{
int s;
switch(c)
{
case 1:s=a+b;break;
case 2:s=a-b;break;
case 3:s=a*b;break;
case 4:s=division(a,b);break;
}
return s;
}
//输出符号
char Dian::print(int c)
{
if(c==1) cout<<"+";
else if(c==2) cout<<"-";
else if(c==3) cout<<"*";
else cout<<"/";
return 0;
}
//是否继续进行的判断
int Dian::ceshi()
{
int m;
cout<<"您是否继续进行24点游戏,继续请输入1,退出请按0:";
cin>>m;
if(m==1){
system("cls");
return 1;}
else return 0;
}
//菜单
void Dian::menu()
{
cout<<" 欢迎来到24点小游戏 "<<endl;
cout<<"************************************************"<<endl;
cout<<"******* 1.自己设置四个数字 *******"<<endl;
cout<<"******* 2.系统随机设置 *******"<<endl;
}
int main()
{
int f[4]; //四个1-14的数
int i,j,m,n;//代表四个数的参数
int a,b,c; //符号
int d1,d2,d3; //每步的结果
Dian dian;
int temp1,temp2;//介质转换,将大于13的数字转换为小于13的
int flag=1;
while(flag){
dian.menu();
int k;
cin>>k;
if(k==1){
cout<<"请输入四个数字(两者之间用" "分离)"<<endl;
for(i=0;i<4;i++)
{
cin>>temp1;
if(temp1>13){
temp2=temp1%13;
cout<<"将 "<<temp1<<" 转化为 "<<temp2<<endl;
}
else temp2=temp1;
f[i]=temp2;
}
cout<<endl;
}
if(k==2){
for(i=0;i<4;i++)
{
f[i]=rand()%13;//随机产生数
cout<<f[i]<<" ";
}
cout<<endl;
}
for(i=0;i<4;i++) //穷举法进行计算
for(j=0;j<4;j++)
if(j!=i)
for(m=0;m<4;m++)
if(m!=i&&m!=j)
for(n=0;n<4;n++)
if(n!=i&&n!=j&&n!=m)
for(a=1;a<5;a++)
for(b=1;b<5;b++)
for(c=1;c<5;c++)
{
d1=dian.judge(f[i],f[j],a);
d2=dian.judge(d1,f[m],b);
d3=dian.judge(d2,f[n],c);
if(d3==24)
{
cout<<f[i];
cout<<dian.print(a);
cout<<f[j];
cout<<dian.print(b);
cout<<f[m];
cout<<dian.print(c);
cout<<f[n]<<"=24"<<endl;
}
}
cout<<endl;
flag=dian.ceshi();
}
return 0;
}
三、算法说明
24点算法可以归纳为如下数学问题:
给定一组数字集合n1,n2,n3…nk,一个求解目标数m,以及一组计算操作符"+" “-” “" “/” ,求所有由该组数字及操作符组成的多项式表达式集合,其值等于目标数m。
算法思路如下:
1.在集合{n1,n2,n3…nk}中,任取两个数字,如n1,n2,与操作符集合进行组合,分别得到一组表达式:n1n2,n1+n2,n1-n2,n1/n2,n2-n1,n2/n1.(其中由于”-“和”/“操作符,左右互换会导致计算结果不同,所以该组合中,包含”-“和”/“操作符的表达式各有两个,操作数先后顺序不同)。
2.对于新得到的每个表达式,都可以和原集合中剩下的元素,组合成新的集合组,同时,为了计算方便,我将每次得到的表达式,都用”()"包住,以保证计算先后顺序:
{(n1*n2),n3,n4…nk}
{(n1+n2),n3,n4…nk}
{(n1-n2),n3,n4…nk}
{(n1/n2),n3,n4…nk}
{(n2-n1),n3,n4…nk}
{(n2/n1),n3,n4…nk}
3.基于以上方法,对集合中所有元素进行两两组合,并与剩余元素形成新的集合。由此,我们得到了一组元素为k-1个的集合组
4.对新集合组中的每一个集合,重复以上1-3步,可得到一组包含k-2个元素的集合组…以此类推,最后会得到一组集合,其中每个集合都只包含一个元素,这个就是我们合成的最终表达式
5.对第四步得到的表达式集合进行求解,判断其是否等于目标数,将符合条件的过滤出来,即得到所有满足条件的表达式。