用扑克牌计算24点(C)

问题描述:

一副扑克牌的每张牌表示一个数(J、Q、K 分别表示 11、12、13,两个司令都表示 6)。任取4 张牌,即得到 4 个 1~13 的数,请添加运算符(规定为加+ 减- 乘* 除/ 四种)使之成为一个运算式。每个数只能参与一次运算,4 个数顺序可以任意组合,4 个运算符任意取 3 个且可以重复取。运算遵从一定优先级别,可加括号控制,最终使运算结果为 24。请输出一种解决方案的表达式,用括号表示运算优先。如果没有一种解决方案,则输出 -1 表示无解

解决方案:

#include <stdio.h>
#define N 4
// 五种优先级方式 
static double first(double num1, double num2, double num3, double num4, int opt1, int opt2, int opt3);

static double second(double num1, double num2, double num3, double num4, int opt1, int opt2, int opt3);

static double third(double num1, double num2, double num3, double num4, int opt1, int opt2, int opt3);

static double four(double num1, double num2, double num3, double num4, int opt1, int opt2, int opt3);

static double fifth(double num1, double num2, double num3, double num4, int opt1, int opt2, int opt3);

static int random_symbols(int all[], char opt[]);

static double compute(double num1, double num2, int opt);



int main()
{
	int num[N];
	char opt[N] = {'+', '-', '*', '/'};
	int i, j, k, g;
	// 随机输入4个数
	for(i = 0;i < N;i++)
	{
		scanf("%d", &num[i]);
		if(num[i] > 13 || num[i] < 1)
		{
			return 1;
		}
	 } 
	for(i = 0;i < N;i++)
	{
		for(j = 0;j < N;j++)
		{
			if(i == j) continue;
			for(k = 0;k < N;k++)
			{
				if(k == i || k == j) continue;
				for(g = 0;g < N;g++)
				{
					if(g == i || g == j || g == k) continue;
					//  这时拿到了不重复的输入的4个数的排序吧 
					int all[N] = {num[i], num[j], num[k], num[g]};
					int value = random_symbols(all, opt);
					// 数组传入实参时只写数组名 
					if(value == 1)
					{
						return 0;
					}
				}
			}
		}
	}
	printf("-1");
	// 如果无解则返回-1 
	return 0;
}

// 数组传入形参在变量名后加[] 
static int random_symbols(int all[], char opt[])
{
	int i, j, k, g;
	double sum = 0;
	for(i = 0;i < N;i++)
	{
		for(j = 0;j < N;j++)
		{
			for(k = 0;k < N;k++)
			{
				sum =  first(all[0], all[1], all[2], all[3], i, j, k);
				 //((A opt B) opt C) opt D
				if(sum == 24)
				{
					printf("((%d%c%d)%c%d)%c%d", all[0], opt[i], all[1], opt[j], all[2], opt[k], all[3]);
					return 1;
				}
				//(A opt (B opt C)) opt D
				sum = second(all[0], all[1], all[2], all[3], i, j, k);
				if(sum == 24)
				{
					printf("(%d%c(%d%c%d)%c%d)", all[0], opt[i], all[1], opt[j], all[2], opt[k], all[3]);
					return 1;
				}
				//A opt (B opt (C opt D))
				sum = third(all[0], all[1], all[2], all[3], i, j, k);
				if(sum == 24)
				{
					printf("%d%c(%d%c(%d%c%d))", all[0], opt[i], all[1], opt[j], all[2], opt[k], all[3]);
					return 1;
				}
				//A opt ((B opt C) opt D)
				sum = four(all[0], all[1], all[2], all[3], i, j, k);
				if(sum == 24)
				{
					printf("%d%c((%d%c%d)%c%d)", all[0], opt[i], all[1], opt[j], all[2], opt[k], all[3]);
					return 1;
				}
				//(A opt B) opt (C opt D)
				sum = fifth(all[0], all[1], all[2], all[3], i, j, k);
				if(sum == 24)
				{
					printf("(%d%c%d)%c(%d%c%d)", all[0], opt[i], all[1], opt[j], all[2], opt[k], all[3]);
					return 1;
				}
			}
		}
	}
	return 0;
}


// 0, 1, 2, 3  分别代表 加减乘除 
static double compute(double num1, double num2, int opt)
{
	double sum1;
	if(opt == 0)
	{
		sum1 = num1 + num2;
	}
	if(opt == 1)
	{
		sum1 = num1 - num2;
	}
	if(opt == 2)
	{
		sum1 = num1 * num2;
	}
	if(opt == 3)
	{
		sum1 = num1 / num2;
	}
	return sum1;
}
/* 四个操作数,三个操作符,两个括号,有以下五种计算模式

 1. ((A opt B) opt C) opt D
 2. (A opt (B opt C)) opt D 
 3. A opt (B opt (C opt D)) 
 4. A opt ((B opt C) opt D) 
 5. (A opt B) opt (C opt D)  */
// 第一种  
static double first(double num1, double num2, double num3, double num4, int opt1, int opt2, int opt3)
{
	//((A opt B) opt C) opt D
	double r1, r2, r3;
	r1 = compute(num1, num2, opt1);
	r2 = compute(r1, num3, opt2);
	r3 = compute(r2, num4, opt3);
	return r3;
}


//第二种 
static double second(double num1, double num2, double num3, double num4, int opt1, int opt2, int opt3)
{
	//(A opt (B opt C)) opt D
	double r1, r2, r3;
	r1 = compute(num2, num3, opt2);
	r2 = compute(num1, r1, opt1);
	r3 = compute(r2, num4, opt3);
	return r3;
}


//第三种 
static double third(double num1, double num2, double num3, double num4, int opt1, int opt2, int opt3)
{
	//A opt (B opt (C opt D))
	double r1, r2, r3;
	r1 = compute(num3, num4, opt3);
	r2 = compute(num2, r1, opt2);
	r3 = compute(num1, r2, opt1);
	return r3;
}



//第四种 
static double four(double num1, double num2, double num3, double num4, int opt1, int opt2, int opt3)
{
	//A opt ((B opt C) opt D) 
	double r1, r2, r3;
	r1 = compute(num2, num3, opt2);
	r2 = compute(r1, num4, opt3);
	r3 = compute(num1, r2, opt1);
	return r3;
}



//第五种 
static double fifth(double num1, double num2, double num3, double num4, int opt1, int opt2, int opt3)
{
	//(A opt B) opt (C opt D)
	double r1, r2, r3;
	r1 = compute(num1, num2, opt1);
	r2 = compute(num3, num4, opt3);
	r3 = compute(r1, r2, opt2);
	return r3;
}
  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

时越zz

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值