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




扑克牌24点游戏是一种玩法类似于上面提到的数学游戏的游戏。以下是一个C语言实现,可以用扑克牌进行游戏: ```c #include <stdio.h> #include <stdlib.h> #include <time.h> int check(double a, double b, double c, double d) { double exp[5]; int i, j, k, l, m; for (i = 0; i < 4; i++) { for (j = 0; j < 4; j++) { if (j == i) continue; for (k = 0; k < 4; k++) { if (k == i || k == j) continue; for (l = 0; l < 4; l++) { if (l == i || l == j || l == k) continue; exp[0] = a; exp[1] = b; exp[2] = c; exp[3] = d; for (m = 0; m < 5; m++) { if (m == 0) exp[m] = exp[i] + exp[j]; else if (m == 1) exp[m] = exp[i] - exp[j]; else if (m == 2) exp[m] = exp[i] * exp[j]; else if (m == 3 && exp[j] != 0) exp[m] = exp[i] / exp[j]; else continue; exp[i] = exp[k]; exp[j] = exp[l]; exp[k] = exp[m]; if (k > l) { int temp = k; k = l; l = temp; } exp[l] = exp[3]; if (exp[2] == 24) return 1; } } } } } return 0; } int main() { int i, j, k, l; double a, b, c, d; srand(time(NULL)); while (1) { i = rand() % 13 + 1; j = rand() % 13 + 1; k = rand() % 13 + 1; l = rand() % 13 + 1; if (check(i, j, k, l)) { printf("找到了一组可以得到24的扑克牌:"); if (i == 1) printf("A "); else if (i == 11) printf("J "); else if (i == 12) printf("Q "); else if (i == 13) printf("K "); else printf("%d ", i); if (j == 1) printf("A "); else if (j == 11) printf("J "); else if (j == 12) printf("Q "); else if (j == 13) printf("K "); else printf("%d ", j); if (k == 1) printf("A "); else if (k == 11) printf("J "); else if (k == 12) printf("Q "); else if (k == 13) printf("K "); else printf("%d ", k); if (l == 1) printf("A "); else if (l == 11) printf("J "); else if (l == 12) printf("Q "); else if (l == 13) printf("K "); else printf("%d ", l); printf("\n"); break; } } return 0; } ``` 这个程序中,使用了和上面类似的`check`函数来判断给定的四张扑克牌是否可以得到24。程序使用了`rand()`函数来生成四张随机的扑克牌,如果可以得到24,则输出这四张牌的面值。如果不行,则继续生成新的组合,直到找到一组可以得到24的牌为止。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值