题目:http://www.patest.cn/contests/ds/2-08
一副扑克牌的每张牌表示一个数(J、Q、K分别表示11、12、13,两个司令都表示6)。任取4张牌,即得到4个1~13的数,请添加运算符(规定为加+ 减- 乘* 除/ 四种)使之成为一个运算式。每个数只能参与一次运算,4个数顺序可以任意组合,4个运算符任意取3个且可以重复取。运算遵从一定优先级别,可加括号控制,最终使运算结果为24。请输出一种解决方案的表达式,用括号表示运算优先。如果没有一种解决方案,则输出-1表示无解。
输入格式说明:
输入在一行中给出4个整数,每个整数取值在[1, 13]。
输出格式说明:
输出一种解决方案的表达式,用括号表示运算优先。如果没有解决方案,请输出-1。
样例输入与输出:
序号 | 输入 | 输出 |
1 | 2 3 12 12 | ((3-2)*12)+12 |
2 | 5 5 5 5 | (5*5)-(5/5) |
3 | 1 3 5 6 | (1+(3*6))+5 |
4 | 8 13 9 4 | 8+((13-9)*4) |
5 | 2 13 7 7 | 2*(13-(7/7)) |
6 | 5 5 5 2 | -1 |
使用穷举法
四操作数,三个操作符,两个括号,有以下五种计算模式
((A op B) op C) op D
(A op (B op C)) op D
A op (B op (C op D))
A op ((B op C) op D)
(A op B) op (C op D)
之前用 int型, 发现几个测试点一直无法通过,后改成double , 测试全部通过
import java.util.Scanner;
/**
* @author chenhong
*
*四操作数,三个操作符,两个括号,有以下五种计算模式
((A op B) op C) op D
(A op (B op C)) op D
A op (B op (C op D))
A op ((B op C) op D)
(A op B) op (C op D)
*
* */
public class Main {
public static double cal(double x, double y, int op)
{
switch(op)
{
case 1: return x+y;
case 2: return x-y;
case 3: return x*y;
case 4: return x/y;
default : return 0;
}
}
/**
* ((A op B) op C) op D
* */
public static double calculateMode1(double num1,double num2,double num3,double num4,int op1,int op2,int op3)
{
double r1,r2,r3;
r1 = cal(num1,num2,op1);
r2 = cal(r1,num3,op2);
r3 = cal(r2,num4,op3);
return r3;
}
/**
* (A op (B op C)) op D
* */
public static double calculateMode2(double num1,double num2,double num3,double num4,int op1,int op2,int op3)
{
double r1,r2,r3;
r1 = cal(num2,num3,op2);
r2 = cal(num1,r1,op1);
r3 = cal(r2,num4,op3);
return r3;
}
/**
* A op (B op (C op D))
* */
public static double calculateMode3(double num1,double num2,double num3,double num4,int op1,int op2,int op3)
{
double r1,r2,r3;
r1 = cal(num3,num4,op3);
r2 = cal(num2,r1,op2);
r3 = cal(num1,r2,op1);
return r3;
}
/**
* A op ((B op C) op D)
* */
public static double calculateMode4(double num1,double num2,double num3,double num4,int op1,int op2,int op3)
{
double r1,r2,r3;
r1 = cal(num2,num3,op2);
r2 = cal(r1,num4,op3);
r3 = cal(num1,r2,op1);
return r3;
}
/**
* (A op B) op (C op D)
* */
public static double calculateMode5(double num1,double num2,double num3,double num4,int op1,int op2,int op3)
{
double r1,r2,r3;
r1 = cal(num1,num2,op1);
r2 = cal(num3,num4,op3);
r3 = cal(r1,r2,op2);
return r3;
}
public static boolean get24(int[] arr,char[] op)
{
//穷举所有运算组合
for(int i=1;i<=4;i++)
{
for(int j=1;j<=4;j++)
{
for(int k=1;k<=4;k++)
{
double sum =0;
sum =calculateMode1(arr[0],arr[1],arr[2],arr[3],i,j,k);
if(sum==24)
{
//((A op B) op C) op D
System.out.printf("((%d%c%d)%c%d)%c%d\n",arr[0],op[i],arr[1],op[j],arr[2],op[k],arr[3]);
return true;
}
sum = calculateMode2(arr[0],arr[1],arr[2],arr[3],i,j,k);
if(sum==24)
{
//(A op (B op C)) op D
System.out.printf("(%d%c(%d%c%d))%c%d\n",arr[0],op[i],arr[1],op[j],arr[2],op[k],arr[3]);
return true;
}
sum = calculateMode3(arr[0],arr[1],arr[2],arr[3],i,j,k);
if(sum==24)
{
//A op (B op (C op D))
System.out.printf("%d%c(%d%c(%d%c%d))\n",arr[0],op[i],arr[1],op[j],arr[2],op[k],arr[3]);
return true;
}
sum = calculateMode4(arr[0],arr[1],arr[2],arr[3],i,j,k);
if(sum==24)
{
//A op ((B op C) op D)
System.out.printf("%d%c((%d%c%d)%c%d)\n",arr[0],op[i],arr[1],op[j],arr[2],op[k],arr[3]);
return true;
}
sum = calculateMode5(arr[0],arr[1],arr[2],arr[3],i,j,k);
if(sum==24)
{
//(A op B) op (C op D)
System.out.printf("(%d%c%d)%c(%d%c%d)\n",arr[0],op[i],arr[1],op[j],arr[2],op[k],arr[3]);
return true;
}
}
}
}
//如果没有解决方案
return false;
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int[] arr = new int[4];
char[] op = new char[]{'#','+','-','*','/'};
for(int i=0;i<4;i++)
{
arr[i]= scanner.nextInt();
}
//遍历所有数字的组合
for(int i=0;i<4 ;i++)
{
for(int j=0;j<4;j++)
{
if(i==j) continue;
for(int k=0;k<4;k++)
{
if(i==k || j==k) continue;
for(int t=0;t<4;t++)
{
if(i==t || j==t || k==t) continue;
int[] newarr = new int[]{arr[i],arr[j],arr[k],arr[t]};
if(get24(newarr,op))
{
return ;
}
}
}
}
}
//无解
System.out.println("-1");
}
}