0
点赞
收藏
分享

微信扫一扫

2.22 算法练习

爱我中华8898 2022-02-22 阅读 69

说明

24点

24点

做题情况

思路

代码

/*
问题描述
  24点游戏是一个非常有意思的游戏,很流行,玩法很简单:
给你4张牌,每张牌上有数字(其中A代表1,J代表11,Q代表12,K代表13),
你可以利用数学中的加、减、乘、除以及括号想办法得到24,例如:
  ((A*K)-J)*Q等价于((1*13)-11)*12=24
  加减乘不用多说了,但除法必须满足能整除才能除!
这样有一些是得不到24点的,所以这里只要求求出不超过24的最大值。
输入格式
  输入第一行N(1<=N<=5)表示有N组测试数据。每组测试数据输入4行,每行一个整数(1到13)表示牌值。
输出格式
  每组测试数据输出一个整数,表示所能得到的最大的不超过24的值。
*/

#include<iostream>

using namespace std;

int n;
int a[5];//用于存储数字 
int bol[5]={0,0,0,0,0};//用于判断是否用过 

int ans=0; 

int m,b;//找到没有用过的那两个
int nu=0;
int x1,x2,x3,x4,flag=0;

void dfs(int layer,int num){
	//layer 表示用了多少数,num表示当前得到的结果 
	
	if(layer==4){//递归出口 
		if(num>ans&&num<=24)
			ans=num;
		return ;
	}
	
	if(layer==2){//考虑两两结合的情况
			nu=0;
		for(int i=1;i<=4;i++){
			if(bol[i]==0&&nu==0){
				m=a[i];
				nu++;
			} 
			if(bol[i]==0&&nu==1)
				b=a[i];
		} 
		
		//现在我们有的数字就是num,m,b;
		//由于本次情况是单独研究两两结合的,因此只考虑m+b,m-b,m*b,m/b和num的组合
		//我就直接枚举了 
		x1=m+b;x2=m-b;x3=m*b;flag=0;
		if(m%b==0) {x4=m/b;flag=1;}

		
		if(num+x1>ans&&num+x1<=24)	ans=num+x1;
		if(num-x1>ans&&num-x1<=24)	ans=num-x1;
		if(num*x1>ans&&num*x1<=24)	ans=num*x1;
		if(x1!=0) if(num%x1==0)	if(num%x1>ans&&num%x1<=24)	ans=num%x1;
		
		if(num+x2>ans&&num+x2<=24)	ans=num+x2;
		if(num-x2>ans&&num-x2<=24)	ans=num-x2;
		if(num*x2>ans&&num*x2<=24)	ans=num*x2;
		if(x2!=0) if(num%x2==0)	if(num%x2>ans&&num%x2<=24)	ans=num%x2;
		
		if(num+x3>ans&&num+x3<=24)	ans=num+x3;
		if(num-x3>ans&&num-x3<=24)	ans=num-x3;
		if(num*x3>ans&&num*x3<=24)	ans=num*x3;
		if(x3!=0) if(num%x3==0)	if(num%x3>ans&&num%x3<=24)	ans=num%x3;
		
		if(flag){//如果存在x4 
			if(num+x4>ans&&num+x4<=24)	ans=num+x4;
			if(num-x4>ans&&num-x4<=24)	ans=num-x4;
			if(num*x4>ans&&num*x4<=24)	ans=num*x4;
			if(x4!=0) if(num%x4==0)	if(num%x4>ans&&num%x4<=24)	ans=num%x4;
		}
		
	}
	
	//下面直接枚举四种运算
	
	//加法
	for(int i=1;i<=4;i++){
		if(bol[i]==0){//如果没用过
			bol[i]=1; 
			dfs(layer+1,num+a[i]);
			bol[i]=0;
		}
	} 
	
	//减法 
	for(int i=1;i<=4;i++){
		if(bol[i]==0){//如果没用过
			if(num>=a[i]){
				bol[i]=1; 
				dfs(layer+1,num-a[i]);
				bol[i]=0;	
			} 
		}
	} 
	
	//乘法 
	for(int i=1;i<=4;i++){
		if(bol[i]==0){//如果没用过
			bol[i]=1; 
			dfs(layer+1,num*a[i]);
			bol[i]=0;
		}
	} 
	
	//除法 
	for(int i=1;i<=4;i++){
		if(bol[i]==0){//如果没用过
		//并且可以整除 
		if(num%a[i]==0){
			bol[i]=1; 
			dfs(layer+1,num/a[i]);
			bol[i]=0;
			}
		}
	} 
}



int main(){
	cin>>n;
	while(n--){
		for(int i=1;i<=4;i++)
			cin>>a[i];
		
		ans=0;//最大的数
		
		for(int i=1;i<=4;i++){
			bol[i]=1;
			dfs(1,a[i]);
			bol[i]=0;
		}
		
		cout<<ans<<endl;
	}
	return 0;
}

优化

举报

相关推荐

2.22

2.22 作业

2.22作业

053.(2.22)超级有爱日

2.27 算法练习

算法练习(2)

算法练习(3)

0 条评论