//24点游戏
#include<iostream.h>
#include<math.h>
#include<string.h>
#include<stdio.h>
#include<conio.h>
#include<stdlib.h>
#define MAX 4;//最大输入个数。
int k=0;//全局变量 用来判定是否有解
char tp[4]={0,0,0,0},tpt[2000]={0},tptt[2000]={0},tre[2000]={0};//用来消除重复。tp[1-3]用来记录运算式中的3个运算符。
char op[4]={'+','*','-','/'};
void count(float a[],char tem[][25],int n);//a[]中存放要输入的4个数,tem[][25]中放计算步骤,n是a[]中元素的个数。
int q=0,p=0,e=0,w=0,t=0,r=0,g=0,h=0,v=0,u=0,tu=0,te=0;//用于消除重复。
float group[2]={0,0},flow[20]={0},flo[20]={0};// //tem[][25]中放计算步骤,n是a[]中元素的个数。
void main()
{
char br=1;
int d;
while (br==1)
{ float number[4];//放四个数。
char temp[4][25]; //放运算式,初始化放四个数。
cout<<" "<<endl;
cout<<"请在 30 秒内完成"<<endl<<"please insert four numbers:"<<endl;
for(d=0;d<4;d++)
cin>>number[d];//输入四个数
for(d=0;d<4;d++)
{
sprintf(temp[d],"%d",(int) number[d]);
}//初始化temp[d];
count(number,temp,4);//调用count函数。
if (k==0)
cout<<"no answer";
cout<<endl;
cout<<"不能计算,请重新输入:"<<endl;
scanf ("%d",&br);
}
}
void count(float a[],char tem[][25],int n)
{
float b[4];
char tm[4][25];//b[4]和t[4][]作用同上(为 递归之用)。
int i,j,l,x,y;//i,j用来作双循环;l用来作加减乘除的开关;x,y为后面准备递归数据之用。
/************************************************************************************/
//输出部分
if(n==1)
{
if (fabs(a[0]-24)<0.00001)//因为要考虑除法所以用fabs函数求绝对值与24比较。
//相当于等于24时的情况。
{
/************************************************************************************/
//以下是限定输出条件:
if(tp[3]=='-'&&tp[2]=='-'&&tp[1]=='*')
{
if(te==0)
{
cout<<"\n有解为"<<tem[0]<<"=24";//最后的运算式存在tem[0]中
k=1;
te=1;
}
}//对运算符全*的只输出一遍。
else if(tp[3]=='+'&&(tp[2]=='+'||tp[0]=='+')&&tp[1]=='+')
{
if(t==0)
{
cout<<"\n有解为"<<tem[0]<<"=24";//最后的运算式存在tem[0]中
k=1;
t=1;
}
}//对运算符全+的只输出一遍。
else if(tp[3]=='+'&&(tp[2]=='*'||tp[0]=='*')&&tp[1]=='+')
{
if(g==0)
{
cout<<"\n有解为"<<tem[0]<<"=24";//最后的运算式存在tem[0]中
k=1;
g=1;
}
}
else if((tp[3]=='-'&&tp[2]=='+')||(tp[3]=='+'&&tp[2]=='-'))
{
if(w==0)
{
cout<<"\n有解为"<<tem[0]<<"=24";//最后的运算式存在tem[0]中
k=1;
w=1;
}
}//对于第二次运算时取到b[0]时,第一第二个运算符是+,-或-,+的只输出一遍。
else if(tp[3]=='+'&&tp[2]=='+')
{
if(u==0)
{
cout<<"\n有解为"<<tem[0]<<"=24";//最后的运算式存在tem[0]中
k=1;
u=1;
}
}//对于第二次运算时取到b[0]时,第一第二个运算符是+,+的只输出一遍
else if(tp[3]=='*'&&tp[2]=='*')
{
if(r==0)
{
cout<<"\n有解为"<<tem[0]<<"=24";//最后的运算式存在tem[0]中
k=1;
r=1;
}
}
else if(tp[3]=='*'&&tp[0]=='*'&&tp[1]=='+')
{
if(tu==0)
{
cout<<"\n有解为"<<tem[0]<<"=24";//最后的运算式存在tem[0]中
k=1;
tu=1;
}
}
else
{ for(h=0;h<q;h++)
{
if(group[0]==flow[h])
{
if(tp[3]==tpt[h])
{
if(tp[2]=tptt[h])
{
if(group[1]==flo[h])
{
if(p==0)
{
cout<<"\n有解为"<<tem[0]<<"=24";//最后的运算式存在tem[0]中
k=1;
p=1;
}
}
}
}
}
else if(h==q-1)
{
cout<<"\n有解为"<<tem[0]<<"=24";//最后的运算式存在tem[0]中
k=1;
}
}
}
flo[q]=group[1];//限定条件初始化。
flow[q] =group[0];//限定条件初始化。
tpt[q]=tp[3];//限定条件初始化。
tptt[q]=tp[2];//限定条件初始化。
tre[q]=tp[1];//限定条件初始化。
tp[0]=0;
tp[1]=0;
tp[2]=0;
tp[3]=0;
q=q+1;
}
}
/************************************************************************************/
//运算部分:
if(n>1)//该条件语句用来结束一次递归。
{
for(i=0;i<n;i++)//对n个 数做'+','*','-','/'遍历。
{
for(j=0;j<n;j++)
{
if(i==j) continue;
for(l=0;l<4;l++)//进行四则运算。
{
switch(l)
{
case(0): if(n==2)
{
b[0]=a[0]+a[1]; break;
}
else b[0]=a[i]+a[j]; break;
case(1):if(n==2)
{
b[0]=a[0]*a[1]; break;
}
else b[0]=a[i]*a[j];
break;
//对加和乘做遍历时去除a[i]+a[j]与a[j]+a[i]等情况
case(2):
b[0]=a[i]-a[j];
break;
case(3):
if(a[j]==0)
break;
b[0]=a[i]/a[j];
break; //对'-'和'/'做遍历时考虑a[i]-a[j]与a[j]-a[i]的不同。
default:break;
}//switch
if(l!=3||a[j]!=0)//为递归准备数据(把没用到的数也放到b[]与tm[]中)。
{
{if(l==0||l==2||l==3) //用sprintf函数将运算式输出到数祖tm[]中。
//在输入运算式的同时把括号输到tm[]中。
sprintf(tm[0],"(%s%c%s)",tem[i],op[l],tem[j]);
if(l==1)
sprintf(tm[0],"%s%c%s",tem[i],op[l],tem[j]);
}
{if(n==3)//提取第一次运算的运算符与运算结果。
{
group[1]=b[0];
if(i!=0&&j!=0)
tp[0]=op[l];
else
tp[n-1]=op[l];
}
else if(n==4)//提取第二次运算的运算符与运算结果。
{
tp[n-1]=op[l];
group[0]=b[0];
}
else //提取第三次运算的运算符。
tp[n-1]=op[l];
}
for(x=0,y=1;x<n;x++)//备份没用到的数据(为递归之用)。
{
if(x!=i&&x!=j)
{
b[y]=a[x];
strcpy(tm[y],tem[x]);//复制字符串。
y++;
}//if
}//for
}//if
count(b,tm,n-1);
}//第三层for循环结束。
}//第二层for循环结束。
}//for循环结束。
}//if 结束。
}//count函数结束。