题目描述
问题描述:给出4个1-10的数字,通过加减乘除,得到数字为24就算胜利
输入:
4个1-10的数字。[数字允许重复,测试用例保证无异常数字]
输出:
true or false
这个问题首先能够想到的做法就是暴力枚举,但是这样的话情况太多,写的也太麻烦了点。
所以用递归的方法来做是很方便的。但是要注意到的是,所给的4个数字的运算顺序并不一定是输入的顺序,而且加括号也是允许的。所以我的解决方法是,对4个数字进行全排列,对操作符的选择进行递归,这样不怕找不出一种合适的情况来。找到第一种正确情况时,打印并结束程序,没找到的话,打印false并结束程序。
为了考虑到加括号的情况,递归中有两种步长选择,一种是一步,一种是两步,说白了就是在当前的结果上再加减乘除一个还是两个数,如果是两个数的话,不就相当于它们两先在括号中运算好,再和当前值相运算吗?
dfs方法中m表示当前值,i代表当前操作数的角标,tc是输入4个数的一种全排列。
import java.util.Arrays;
import java.util.List;
import java.util.ArrayList;
import java.util.Scanner;
public class Main{
public static int[] nu;
public static boolean dfs(Integer[] tc,int i,int m){
if(i>=4){
if(m==24){
//System.out.println(Arrays.toString(tc));
return true;
}else{
return false;
}
}
if(i+1<4){
int tem1 = tc[i];
int tem2 = tc[i+1];
return
dfs(tc,i+2,m+(tem1+tem2))||
dfs(tc,i+2,m+(tem1-tem2))||
dfs(tc,i+2,m+(tem1*tem2))||
(tem2!=0 && dfs(tc,i+2,m+(tem1/tem2)))||
dfs(tc,i+2,m-(tem1+tem2))||
dfs(tc,i+2,m-(tem1-tem2))||
dfs(tc,i+2,m-(tem1*tem2))||
(tem2!=0 && dfs(tc,i+2,m-(tem1/tem2)))||
dfs(tc,i+2,m*(tem1+tem2))||
dfs(tc,i+2,m*(tem1-tem2))||
dfs(tc,i+2,m*(tem1*tem2))||
(tem2!=0 && dfs(tc,i+2,m*(tem1/tem2)))||
(tem1+tem2!=0 && dfs(tc,i+2,m/(tem1+tem2)))
||(tem1-tem2!=0 && dfs(tc,i+2,m/(tem1-tem2)))
||(tem1*tem2!=0 && dfs(tc,i+2,m/(tem1*tem2)))
||(tem1/tem2!=0 && dfs(tc,i+2,m/(tem1/tem2)))
||
dfs(tc,i+1,m+tc[i])||
dfs(tc,i+1,m-tc[i])||
dfs(tc,i+1,m*tc[i])||
(tc[i]!=0 && m%tc[i]==0 &&dfs(tc,i+1,m/tc[i]));
}else{
return
dfs(tc,i+1,m+tc[i])||
dfs(tc,i+1,m-tc[i])||
dfs(tc,i+1,m*tc[i])||
(tc[i]!=0&& m%tc[i]==0 && dfs(tc,i+1,m/tc[i]));
}
}
public static List<List<Integer>> permute(int[] nums) {
int N= nums.length;
List<List<Integer>> re = new ArrayList();
if(N==1){
List a = new ArrayList();
a.add(nums[0]);
re.add(a);
return re;
}
int[] annums = new int[N-1];
int la = nums[N-1];
for(int i=0;i<N-1;i++){
annums[i] = nums[i];
}
for(int i=0;i<N;i++){
for(List<Integer> tt : permute(annums)){
tt.add(i, la);
re.add(tt);
}
}
return re;
}
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
while(sc.hasNext()){
boolean flag = false;
String raw = sc.nextLine();
String[] a = raw.split(" ");
nu = new int[4];
for(int i=0;i<4;i++){
nu[i] = Integer.valueOf(a[i]);
}
List re = permute(nu);
int N = re.size();
for(int i=0;i<N;i++){
List<Integer> c = (List) re.get(i);
Integer[] tc = new Integer[4];
c.toArray(tc);
//System.out.println(Arrays.toString(tc));
if(dfs(tc,0,0)==true){
System.out.println(true);
flag = true;
break;
}
}
//System.out.println(dfs(new Integer[]{10,2,5,1},0,0));
if(flag == false)
System.out.println(false);
}
}
}