2-08. 用扑克牌计算24点(25)

题目: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");
		
		
		
	}
}




你可能感兴趣的:(ACM&PAT)