好了,这回我先上代码
#include<iostream>
#include<string>
#include<windows.h>
#include<cmath>
using namespace std;
int jishu=0;
//twenty-four point Terminator
// 作者:锋利5钻石剑 sharpness five enchanted_diamond sword
//修改日期:2024.7.9
//修改内容:判断是否等于24时设置了不超过1e-5的误差限,以防在除法过程中损失精度,还有难度自动评判(目前还有BUG,如果遇到了请不要喷)
void input();//将输入的字符串存储到字符串类数组str[]中,再转化为对应的整数num[]
double cal(double,double,int s);//四则运算,s表示符号
bool int_right(int x[],int i);//判断该数组下标为i的元素是否与前面元素相同,无相同则为true,有相同则为false
void point24(int n);//计算24点的第一种情况,如((a+b)*c)/d
void point24_2();//计算24点的第二种情况,如(a+b)*(c+d)
void output(int a);//根据第a种情况以及数组newnum[]和sig[]的内容输出
string str[4];//输入的字符串
int num[4],newnum[4], sig[3];
//num[]是把字符串转换成数字之后的数组;newnum[]存储不同顺序的数字;
//sig[]表示数字之间的符号
double res[4];//中间结果
bool success;
//四则运算,s表示符号
double cal(double x,double y,int s)
{
double result=0;
switch(s)
{
case 0:result=x+y;break;
case 1:result=x-y;break;
case 2:result=x*y;break;
case 3:result=x/y;break;
case 4:result=y-x;break;
case 5:result=y/x;break;
}
return result;
}
void point24(int n)//计算24点的第一种情况
{
res[3]=newnum[3];
int i;
if(n==1)
for(i=0;i<=5;i++)
{
jishu+=5;
res[0]=cal(res[1],double(newnum[0]),i);
sig[0]=i;
if(fabs(res[0]-24.0)<=1e-5)
{
success=true;
return;
}
}
else
for(i=0;i<=5;i++)
{
jishu+=5;
res[n-1]=cal(res[n],double(newnum[n-1]),i);
sig[n-1]=i;
point24(n-1);
if(success==true)break;
}
}
void point24_2()//计算24点的第二种情况,其中sig[]不涉及到cal()中的case4和5
{
for(sig[0]=0;sig[0]<=3;sig[0]++)
{
jishu+=5;
res[0]=cal(double(newnum[0]),double(newnum[1]),sig[0]);
for(sig[2]=0;sig[2]<=3;sig[2]++)
{
jishu+=5;
res[1]=cal(double(newnum[2]),double(newnum[3]),sig[2]);
for(sig[1]=0;sig[1]<=3;sig[1]++)
{
jishu+=5;
res[2]=cal(res[0],res[1],sig[1]);
if(fabs(res[2]-24.0)<=1e-5)
{
success=true;
return;
}
}
}
}
}
//判断该数组下标为i的元素是否与前面元素相同,无相同则为true,有相同则为false
bool int_right(int x[],int i)
{
int j=0;
while(j<i)
{
jishu+=5;
if(x[j]==x[i])return false;
j++;
}
return true;
}
void input()//将输入的字符串存储到字符串类数组str[]中,再转化为对应的整数num[]
{
cout<<"【AI】请输入A、2到10、J、Q、K中的四个,计算24点。(A代表1,J代表11,Q代表12,K代表13)"<<endl;
int i;
bool input_right;
for(i=0;i<4;i++)
{
do
{
jishu+=5;
input_right=true;
cin>>str[i];
if(str[i]=="A"||str[i]=="a")num[i]=1;
else if(str[i]=="10")num[i]=10;
else if(str[i]=="J"||str[i]=="j")num[i]=11;
else if(str[i]=="Q"||str[i]=="q")num[i]=12;
else if(str[i]=="K"||str[i]=="k")num[i]=13;
else if(str[i].size()==1&&str[i][0]>='2'&&str[i][0]<='9')
num[i]=str[i][0]-48;
else
{
cout<<"第"<<i+1<<"个输入错误,请重输!"<<endl;
input_right=false;
}
}while(input_right==false);
}
}
void output(int a)//根据第a种情况以及数组newnum[]和sig[]的内容输出
{
const char ch[6]={'+','-','*','/','-','/'};
const string outstr[14]={"\0","A","2","3","4","5","6","7","8","9","10","J","Q","K"};
if(a==1)
{
string ansstr=outstr[newnum[3]];
int n;
for(n=2;n>=0;n--)
{
if(sig[n]>=0&&sig[n]<=3)ansstr=ansstr+ch[sig[n]]+outstr[newnum[n]];
else ansstr=outstr[newnum[n]]+ch[sig[n]]+ansstr;
if(n>0)ansstr='('+ansstr+')';
}
cout<<ansstr<<"=24"<<endl;
}
if(a==2)
{
cout<<'('<<outstr[newnum[0]]<<ch[sig[0]]<<outstr[newnum[1]]<<')'<<ch[sig[1]];
cout<<'('<<outstr[newnum[2]]<<ch[sig[2]]<<outstr[newnum[3]]<<')'<<"=24"<<endl;
}
}
int main()//采用回溯法列出每一个排列。然后对每个排列计算24点,成功则结束。
{
OOOO:
input();
int i=0,n;
int B[4]={0,1,2,3};
//B[]是0,1,2,3四个数的排列
while(i>=0&&success==false)
{
jishu+=5;
if(int_right(B,i)==true)
{
while(i<3)
{
jishu+=5;
i++;
if(int_right(B,i)==false)break;
}
if(i==3&&int_right(B,i)==true)
{//下面将num[]的值变换顺序后赋给newnum[],然后运用两种方法算24点
for(n=0;n<4;n++){newnum[n]=num[B[n]];jishu+=5;}
point24(3);
if(success==true)output(1);
else
{
point24_2();
if(success==true)output(2);
}
}
}
while(B[i]==3&&i>=0)
{
B[i]=0;//置0
i--;//回溯
jishu+=5;
}
if(i>=0)B[i]++;//该位的值加一
}
if(success==false){cout<<"不能算出24"<<endl;return 0;}
cout << "难度系数:" << jishu << "难度等级:";
if(jishu<=1000)
{
cout << "简单";
}
else if(jishu<=5000)
{
cout << "普通";
}
else if(jishu<=20000)
{
cout << "困难";
}
else
{
cout << "炼狱";
}
return 0;
}