24点问题

1、 问题描述

24点游戏是经典的纸牌益智游戏。
常见游戏规则:
从扑克中每次取出4张牌。使用加减乘除,第一个能得出24者为赢。(其中,J代表11,Q代表12,K代表13,A代表1),按照要求编程解决24点游戏。
基本要求: 随机生成4个代表扑克牌牌面的数字字母,程序自动列出所有可能算出24的表达式。

2、 算法构造

应用穷举法搜索整个解集,筛选出符合题目要求的全部解。关键的问题是如何确定该题的解集。假设输入的4个整数为A、B、C、D,如果不考虑括号优先级的情况,仅用四则运算符将它们连接,例如:A+BC/D,利用数学排列组合求得共有64种表达式情形。如果考虑加括号的情况,暂不考虑运算符,共有以下5种情形:
(1)((A□B)□C)□D
(2)(A□(B□C))□D
(3)A□(B□(C□D))
(4)A□((B□C)□D)
(5)(A□B)□(C□D)
其中□代表(±
/)任意的运算符。将上面两种情况综合起来考虑,每输入4个整数,其构成的解集为64*5=320种表达式。也就是说,每输入4个整数,无论以什么方式或优先级进行四则运算,其结果都会在这320种答案之中。我们就是要在这320种表达式中寻找出计算结果为24的表达式。

3、 源程序

#include<stdio.h>
#include<stdlib.h>
#include<time.h>
char symbol[4]={'+','-','*','/'};  //定义四个符号的数组 
float cal(float x,float y,int n)   //两个数之间的四种运算情况 
{
	switch(n)
	{
		case 1:return x+y;
		case 2:return x-y;
		case 3:return x*y;
		case 4:return x/y;
	}
}
//对应表达式类型:((A□B)□C)□D
float calculate1(float i,float j,float k,float t,int n1,int n2,int n3)
{
	float r1,r2,r3;
	r1=cal(i,j,n1);
	r2=cal(r1,k,n2);
	r3=cal(r2,t,n3);
	return r3;
}
//对应表达式类型:(A□(B□C))□D 
float calculate2(float i,float j,float k,float t,int n1,int n2,int n3)
{
	float r1,r2,r3;
	r1=cal(j,k,n1);
	r2=cal(i,r1,n2);
	r3=cal(r2,t,n3);
	return r3;
}
//对应表达式类型:A□(B□(C□D))
float calculate3(float i,float j,float k,float t,int n1,int n2,int n3)
{
	float r1,r2,r3;
	r1=cal(k,t,n1);
	r2=cal(j,r1,n2);
	r3=cal(i,r2,n3);
	return r3;
}
//对应表达式类型:A□((B□C)□D)
float calculate4(float i,float j,float k,float t,int n1,int n2,int n3)
{
	float r1,r2,r3;
	r1=cal(j,k,n1);
	r2=cal(r1,t,n2);
	r3=cal(i,r2,n3);
	return r3;
}
//对应表达式类型:(A□B)□(C□D)
float calculate5(float i,float j,float k,float t,int n1,int n2,int n3)
{
	float r1,r2,r3;
	r1=cal(i,j,n1);
	r2=cal(k,t,n2);
	r3=cal(r1,r2,n3);
	return r3;
}

int get24(int i,int j,int k,int t)
{
	int n1,n2,n3;
	int flag=0;
	for(n1=0;n1<4;n1++)   //三重循环共64种情况 
	for(n2=0;n2<4;n2++)
	for(n3=0;n3<4;n3++)
	{    //以下有五种加括号的方法,总共有64*5=320种情况 
		if(calculate1(i,j,k,t,n1,n2,n3)==24)
		{
			printf("((%d%c%d)%c%d)%c%d=24\n",i,symbol[n1],j,symbol[n2],k,symbol[n3],t);
			flag = 1;
		}
		if(calculate2(i,j,k,t,n1,n2,n3)==24)
		{
			printf("(%d%c(%d%c%d))%c%d=24\n",i,symbol[n1],j,symbol[n2],k,symbol[n3],t);
			flag = 1;
		}
		if(calculate3(i,j,k,t,n1,n2,n3)==24)
		{
			printf("%d%c(%d%c(%d%c%d))=24\n",i,symbol[n1],j,symbol[n2],k,symbol[n3],t);
			flag = 1;
		}
		if(calculate4(i,j,k,t,n1,n2,n3)==24)
		{
			printf("%d%c((%d%c%d)%c%d)=24\n",i,symbol[n1],j,symbol[n2],k,symbol[n3],t);
			flag = 1;
		}
		if(calculate5(i,j,k,t,n1,n2,n3)==24)
		{
			printf("(%d%c%d)%c(%d%c%d)=24\n",i,symbol[n1],j,symbol[n2],k,symbol[n3],t);
			flag = 1;
		}
	}
	return flag;
}
int main()
{
	srand((int)time(0));
	int i,j,k,t;
	int a[4];
	for(i=0;i<4;i++)  //随机产生四个1~13之间的整数 
	{
		a[i]=1+(int)(rand()%13);
	}
	for(i=0;i<4;i++)
	{
		printf("%3d",a[i]);
	}
	printf("\n");
	i=a[0];
	j=a[1];
	k=a[2];
	t=a[3];
	if(get24(i,j,k,t)); 
	else printf("这四个数不能得到24\n");
	getchar();
	return 0; 
}

4、程序测试及调试结果

程序测试结果截图
在这里插入图片描述
程序调试截图
在这里插入图片描述

5、总结体会

此次课程设计题目是24点问题,了解题目之后就是整理思路进行算法设计,我采用的是穷举法,在算法设计中的难点在于考虑所有可能的结果,容易遗漏或考虑不全面。接下来是程序的编写和调试,编写过程比较顺利,在第一次运行时我没有设置好随机数字的范围,即随机数中出现了0,我修改了程序,使得随机数范围在1~13之间。至此程序已经完成,功能符合题目要求,但是穷举法比较费时费力,对于24点问题更简便的方法是采用递归算法,下次可以尝试用其他方法解决24点问题。
通过这次学习,我学习到了很多,这个程序难度不是特别大,但是算法比较繁琐,考虑需要细心才行。通过此次程序设计,也让我把平时学习的理论知识运用在了实际问题上,让我对理论更加熟悉。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值