二十四点

  1. 题目

   24点游戏是经典的纸牌益智游戏。

   常见游戏规则:

   从扑克中每次取出4张牌。使用加减乘除,第一个能得出24者为赢。(其中,J代表11,Q代表12,K代表13,A代表1),按照要求编程解决24点游戏。

基本要求: 随机生成4个代表扑克牌牌面的数字字母,程序自动列出所有可能算出24的表达式,用擅长的语言(C/C++/Java或其他均可)实现程序解决问题。

          1.程序风格良好(使用自定义注释模板)

          2.列出表达式无重复。

提高要求:用户初始生命值为一给定值(比如3),初始分数为0。随机生成4个代表扑克牌牌面的数字或字母,由用户输入包含这4个数字或字母的运算表达式(可包含括号),如果表达式计算结果为24则代表用户赢了此局。

         1. 程序风格良好(使用自定义注释模板)

         2.使用计时器要求用户在规定时间内输入表达式,如果规定时间内运算正确则加分,超时或运算错误则进入下一题并减少生命值(不扣分)。

         3.所有成绩均可记录在TopList.txt文件中。

2.编程语言:C语言

3.算法构造

(1)程序设计思路

     1、首先定义一个get()函数,先随机生成四个数字,然后将这四个数字进行四重循环进行穷举,将它们进行排列,一共有4!=24种可能,然后将运算符进行三循环穷举,因为每个运算符位置上都有四种可能,所以共有4*4*4=64种可能。接着调用calculate_A()、calculate_B()、calculate_C()、calculate_D()、calculate_E()五个子函数判断结果是否为24,若是,则输出表达式;

     2、因为得考虑到运算符的优先级,所以得对表达式进行括号的处理,而因为是对是四个数字进行运行,所以表达式中最多有两个括号,所以一共有五种情况,即第一种情况:((a,b),c),d);第二种情况:((a,(b,c)),d);第三种情况:(a,(b,(c,d)));

第四种情况:(a,((b,c),d));第五种情况:((a,b),(c,d))。

4.代码

//title:二十四点
//author:qiuerduoer
//time:2019/04/13
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
char mark[4]={'+','-','*','/'};//定义一个字符数组来存储四个运算符
float cal(float x,float y,int mark)//加减乘除四则运算
{ 
  switch(mark)
  {
    case 0:return x+y;
    case 1:return x-y;
    case 2:return x*y;
    case 3:return x/y;
  }
  return 0;
}

float calculate_A(float a,float b,float c,float d,int mark1,int mark2,int mark3)//第一种情况:((a,b),c),d)
{
  float r1,r2,r3;
  r1=cal(a,b,mark1);
  r2=cal(r1,c,mark2);
  r3=cal(r2,d,mark3);
  return r3;
}
float calculate_B(float a,float b,float c,float d,int mark1,int mark2,int mark3)//第二种情况:((a,(b,c)),d)
{
  float r1,r2,r3;
  r1=cal(b,c,mark2);
  r2=cal(a,r1,mark1);
  r3=cal(r2,d,mark3);
  return r3;
}
float calculate_C(float a,float b,float c,float d,int mark1,int mark2,int mark3)//第三种情况:(a,(b,(c,d)))
{
  float r1,r2,r3;
  r1=cal(c,d,mark3);
  r2=cal(b,r1,mark2);
  r3=cal(a,r2,mark1);
  return r3;
}
float calculate_D(float a,float b,float c,float d,float mark1,float mark2,float mark3)//第四种情况:(a,((b,c),d))
{
  float r1,r2,r3;
  r1=cal(b,c,mark2);
  r2=cal(r1,d,mark3);
  r3=cal(a,r2,mark1);
  return r3;
}
float calculate_E(float a,float b,float c,float d,int mark1,int mark2,int mark3)//第五种情况:((a,b),(c,d))
{
  float r1,r2,r3;
  r1=cal(a,b,mark1);
  r2=cal(c,d,mark3);
  r3=cal(r1,r2,mark2);
  return r3;
}
float get()
{   int f[4];
    int i,j,m,n;
	int mark1,mark2,mark3;
	float flag=0;
  	srand((int)time(NULL));//产生随机种子
	printf("随机生成的数字是:\n");
	for( i=0;i<4;i++)
    {   
		f[i]=rand()%13+1;
	    printf("%d ",f[i]);
    }
	printf("\n");
	printf("符合条件的表达式有:\n");
	//四重循环开始穷举四个随机数,将它们进行排列,共4!=24种可能。
    for(i=0;i<4;i++)
        for(j=0;j<4;j++)
            if(j!=i)
                for(m=0;m<4;m++)
                    if(m!=i&&m!=j)
                        for(n=0;n<4;n++)
                            if(n!=i&&n!=j&&n!=m)
							//三重循环开始穷举四个运算符,每个运算符位置上都有四种可能,所以共4*4*4=64种可能
							for(mark1=0;mark1<4;mark1++)
							{
                                for(mark2=0;mark2<4;mark2++)
								{
                                    for(mark3=0;mark3<4;mark3++)
									{
                                        if(calculate_A(f[i],f[j],f[m],f[n],mark1,mark2,mark3)==24)//判断第一种情况的结果是否满足24
										{
                                           printf("((%d%c%d)%c%d)%c%d=24\n",f[i],mark[mark1],f[j],mark[mark2],f[m],mark[mark3],f[n]);
                                           flag=1;
										}
                                        if(calculate_B(f[i],f[j],f[m],f[n],mark1,mark2,mark3)==24)//判断第二种情况的结果是否满足24
										{
                                           printf("(%d%c(%d%c%d))%c%d=24\n",f[i],mark[mark1],f[j],mark[mark2],f[m],mark[mark3],f[n]);
                                           flag=1;
										}
                                        if(calculate_C(f[i],f[j],f[m],f[n],mark1,mark2,mark3)==24)//判断第三种情况的结果是否满足24
										{
                                           printf("%d%c(%d%c(%d%c%d))=24\n",f[i],mark[mark1],f[j],mark[mark2],f[m],mark[mark3],f[n]);
                                           flag=1;
										}
                                        if(calculate_D(f[i],f[j],f[m],f[n],mark1,mark2,mark3)==24)//判断第四种情况的结果是否满足24
										{
                                           printf("%d%c((%d%c%d)%c%d)=24\n",f[i],mark[mark1],f[j],mark[mark2],f[m],mark[mark3],f[n]);
                                           flag=1;
										}
                                        if(calculate_E(f[i],f[j],f[m],f[n],mark1,mark2,mark3)==24)//判断第五种情况的结果是否满足24
										{
                                           printf("(%d%c%d)%c(%d%c%d)=24\n",f[i],mark[mark1],f[j],mark[mark2],f[m],mark[mark3],f[n]);
                                           flag=1;
										}
									}
	  
								}
							}
    if(flag==0)
	{
		printf("不存在符合条件的表达式!\n");
	}
    return flag; 
}
int main()
{   
	get();
    system("pause");
}

五:测试结果

六、心得

刚开始不知道如何对表达式进行括号处理,然后在网上浏览了许多方法,才知道如何对表达式进行括号处理。该算法还涉及到了数学中的排列与组合知识 ,刚开始还查阅了相关资料复习了下相关知识。通过编写该程序,深刻体会到了数学对程序算法的重要性;还有在编写程序前自己没有充分地将所有问题都考虑充分,以致第一次编译成功时出来的结果不够完善,所以以后在编写程序时,我应当从多个角度思考与考虑问题,这样才可以更高效地完成解决问题;该程序仍存在诸多不足,希望自己能在以后的学习中继续改进。

 

 

 

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值