【C/C++】二十四点终结者 twenty-four point Terminator(现在可以给难度评等级啦!)

好了,这回我先上代码

#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;
}

  • 4
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值