蓝桥杯 试题 算法训练 24点(dfs)

题目链接

按照题目意思是4个数字可以任意排列,数字之间的运算符可以任意,括号可以任意添加,换句话说就是这些数据可以两两按照4种运算自由组合,当两个数字运算组合成为一个中间结果后,此结果又能和未组合的数据进行任意组合,直到只剩一个数字,递归找到所有组合方案,保存最接近24的答案即可。

需要注意的是组合的中间结果可能出现0,因此做除法时需要加上除数不为0的条件。

import java.util.*;
public class Main{
	public static int[] nums=new int[4];
	public static int ans=-0x3f3f3f3f;
	public static void dfs(int[] arr,int cnt) {
		//递归的时候应该对于这三个数一视同仁,也能自由组合
		if(cnt==1) {
			if(arr[0]<=24) {
				ans=Math.max(arr[0], ans);
			}
			return ;
		}
		boolean[] vis=new boolean[cnt];
		Arrays.fill(vis, false);
		for(int i=0;i<cnt;i++) {//双重循环保证arr中任意两个数据可以组合
			vis[i]=true;
			for(int j=0;j<cnt;j++) {
				if(!vis[j]) {
					vis[j]=true;
					int[] newarr=new int[cnt-1];//新组合结果和剩余没组合的数形成一个新数组dfs
					int k=0;
					for(int m=0;m<cnt;m++) {
						if(!vis[m]) {
							newarr[k++]=arr[m];
						}
					}
					newarr[k]=arr[i]+arr[j];
					dfs(newarr,cnt-1);//递归不会修改newarr,所以后面能接着用
					newarr[k]=arr[i]-arr[j];
					dfs(newarr,cnt-1);//递归不会修改newarr,所以后面能接着用
					newarr[k]=arr[i]*arr[j];
					dfs(newarr,cnt-1);//递归不会修改newarr,所以后面能接着用
					if(arr[j]!=0 && arr[i]%arr[j]==0) {
						//因为经过自由组合 arr[j]作为某次组合的中间结果可能为0
						newarr[k]=arr[i]/arr[j];
						dfs(newarr,cnt-1);//递归不会修改newarr,所以后面能接着用
					}
					vis[j]=false;
					
				}
			}
			vis[i]=false;
		}
	}
	public static void main(String[] Agrs) {
		Scanner sc=new Scanner(System.in);
		
		int N;
		N=sc.nextInt();
		for(int t=0;t<N;t++) {
			//Arrays.fill(vis, false);
			ans=-0x3f3f3f3f;
			for(int i=0;i<4;i++) {
				nums[i]=sc.nextInt();
			}
			//对任意两数进行+-*/的组合
			dfs(nums,4);
			System.out.println(ans);
		}
		
	}
}
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值