C语言实现24点小游戏

问题描述

        游戏规则:
        从键盘输入任意1-13的4个数,然后用算术运算符“+、一、*、/”将这四个数组成一一个算术表达式(可加括号,每个数字只能使用1次),使得该式的运算结果为24,每输入一次表达式,系统给出该式的运算结果,如果结果是24,则游戏结束;如果不是,则继续组合表达式,直到结果为24为止。

问题分析

        本题最简单的解法就是应用穷举法搜索整个解的空间,然后筛选出符合项的全部解,因此关键就是如何确定该题的解题空间。

        假设输入4个整数,A,B,C,D,如果只考虑括号不考虑优先级的情况,有一下几种情况:

     (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)

        即在□输入“+、-、*、/”中的任意一种。我们就是在填入的所有式子中所得到的答案里面找出答案为24的表达式。

算法设计

        我们在不同的地方设置不同的变量,即:op1、op2、op3,并且规定A和B之间的运算符为op1,B和C之间的运算符为op2,C和D之间的运算符为op3。即:

      A op1 B op2 C op3 D

        又规定op1、op2、op3的取值范围为1、2、3、4分别为加减乘除,如表所示:

op1、op2、op3变量值表示的运算
1+
2-
3*
4/

此时就得到了以下算法:

	for(op1=1;op1<=4;op1++)
         for(op2=1;op2<=4;op2++)
             for(op3=1;op3<=4;op3++)
             {得到一种不含括号的表达式情形:A op1 B op2 C op3 D
}

        下面我们要填入符号,根据括号和优先级的限制,我们有以下的填入方式
     (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)

        根据优先级来说,以上五种情况包括了全部的算式,我们只需计算出每个表达式的值,将其与24进行比较。

float calculate_model1(float i,float j,float k,float t,
int op1,int op2,int op3)
{ /*对应关系式  ((A□B)□C)□D */
   float r1,r2,r3;
   r1 = cal(i,j,op1);
   r2 = cal(r1,k,op2);
   r3 = cal(r2,t,op3);
   return r3;
 }

float calculate_model2(float i,float j,float k,float t,
int op1,int op2,int op3)
{ /*对应关系式  (A□(B□C))□D */
   float r1,r2,r3;
   r1 = cal(j,k,op2);
   r2 = cal(i,r1,op1);
   r3 = cal(r2,t,op3);
   return r3;
 }

float calculate_model3(float i,float j,float k,float t,
int op1,int op2,int op3)
{ /*对应关系式   A□((B□C)□D) */
   float r1,r2,r3 ;
   r1 = cal(k,t,op3);
   r2 = cal(j,r1,op2);
   r3 = cal(i,r2,op1);
   return r3;
 }

float calculate_model4(float i,float j,float k,float t,
int op1,int op2,int op3)
{ /*对应关系式  ((A□B)□C)□D */
   float r1,r2,r3;
   r1 = cal(j,k,op2);
   r2 = cal(r1,t,op3);
   r3 = cal(i,r2,op1);
   return r3;
 }

float calculate_model5(float i,float j,float k,float t,
int op1,int op2,int op3)
{ /*对应关系式  (A+B)-(C×D) */
   float r1,r2,r3 ;
   r1 = cal(i,j,op1);
   r2 = cal(k,t,op3);
   r3 = cal(r1,r2,op2);
   return r3;
 }

        上述算法中,每一个函数对应一种表达式类型, 其返回值为表达式的值,原表达式式的形式为i opl j op2 k op3 t,不同的表达式类型,根据其运算时优先级的不同进行不同的运算。其中函数cal()的作用是通过每种表达式的状态计算出对应的表达式的值。

     int op1,op2,op3;
     int flag=0;
     for(op1=1;op1<=4;op1++)
         for(op2=1;op2<=4;op2++)
             for(op3=1;op3<=4;op3++)

op1、op2、op3都是取 “+”,“-”,“*”,“/”四个选项

        函数cal()包括3个参数,第3个参数为运算符变量,它标志着不同种类的运算符,前两个参数为运算数。该函数的作用是使用前两个参数指定的操作数进行第3个参数指定的运算,并返回其运算结果。例如函数调用cal(2,3.1)的作用是计算2+3=5.并返回5。函数cal0的代码如下:

float cal(float x,float 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;
  }
}

        将上面所讲的算法进行结合,可以遍历由4个操作数(范围:1-13), 3个运算符(+,-,*,/),这样就缩小了搜索空间,提高查询效率。

主函数

main()
{
         int i,j,k,t;
         printf("Please input four integer (1~13)\n");

输入 i,j,k,t四位数。

 loop:    scanf("%d %d %d %d",&i,&j,&k,&t);
         if(i<1||i>13 || j<1||j>13 || k<1||k>13 || t<1||t>13){
           printf("Input illege, Please input again\n");
           goto loop;
   }

如果这四位数小于1或者大于13,则报错。

      if(i==j||i==k || i==t||j==k || j==t||k==t){
         printf("Input wrong, Please input again\n");
         goto loop;
 }

如果这四位数有一位以上的数输入了2遍,则报错(题目要求只能用一次)

         if(get24(i,j,k,t));
         else 
			 {printf("Sorry, the four integer cannot be calculated to get 24\n");
			  goto loop;} 
 }

如果这四个数通过运算不等于24,则需要重新输入4位数重新计算

goto loop;表示继续执行不退出。

完整代码

以下是完整代码:

#include<stdio.h>
char op[5]={'#','+','-','*','/',};
float cal(float x,float 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;
   }
 }

float calculate_model1(float i,float j,float k,float t,int op1,int op2,int op3)
{
   float r1,r2,r3;
   r1 = cal(i,j,op1);
   r2 = cal(r1,k,op2);
   r3 = cal(r2,t,op3);
   return r3;
 }

float calculate_model2(float i,float j,float k,float t,int op1,int op2,int op3)
{
   float r1,r2,r3;
   r1 = cal(j,k,op2);
   r2 = cal(i,r1,op1);
   r3 = cal(r2,t,op3);
   return r3;
 }

float calculate_model3(float i,float j,float k,float t,int op1,int op2,int op3)
{
   float r1,r2,r3 ;
   r1 = cal(k,t,op3);
   r2 = cal(j,r1,op2);
   r3 = cal(i,r2,op1);
   return r3;
 }

float calculate_model4(float i,float j,float k,float t,int op1,int op2,int op3)
{
   float r1,r2,r3;
   r1 = cal(j,k,op2);
   r2 = cal(r1,t,op3);
   r3 = cal(i,r2,op1);
   return r3;
 }

float calculate_model5(float i,float j,float k,float t,int op1,int op2,int op3)
{
   float r1,r2,r3 ;
   r1 = cal(i,j,op1);
   r2 = cal(k,t,op3);
   r3 = cal(r1,r2,op2);
   return r3;
 }

get24(int i,int j,int k,int t)
{
     int op1,op2,op3;
     int flag=0;
     for(op1=1;op1<=4;op1++)
         for(op2=1;op2<=4;op2++)
             for(op3=1;op3<=4;op3++)
             {
				 if(calculate_model1(i,j,k,t,op1,op2,op3)==24)
				 {
					 printf("((%d%c%d)%c%d)%c%d=24\n",i,op[op1],j,op[op2],k,op[op3],t);
					 flag = 1;
				 }
				 if(calculate_model2(i,j,k,t,op1,op2,op3)==24)
				 {
					 printf("(%d%c(%d%c%d))%c%d=24\n",i,op[op1],j,op[op2],k,op[op3],t);
					 flag = 1;
				 }
				 if(calculate_model3(i,j,k,t,op1,op2,op3)==24)
				 {
					 printf("%d%c(%d%c(%d%c%d))=24\n",i,op[op1],j,op[op2],k,op[op3],t);
					 flag = 1;
				 }
				 if(calculate_model4(i,j,k,t,op1,op2,op3)==24)
				 {
					 printf("%d%c((%d%c%d)%c%d)=24\n",i,op[op1],j,op[op2],k,op[op3],t);
					 flag = 1;
				 }
				 if(calculate_model5(i,j,k,t,op1,op2,op3)==24)
				 {
					 printf("(%d%c%d)%c(%d%c%d)=24\n",i,op[op1],j,op[op2],k,op[op3],t);
					 flag = 1;
				 }
			 }
			 return flag;
} 

main()
{
         int i,j,k,t;
         printf("Please input four integer (1~13)\n");
 loop:    scanf("%d %d %d %d",&i,&j,&k,&t);
         if(i<1||i>13 || j<1||j>13 || k<1||k>13 || t<1||t>13){
           printf("Input illege, Please input again\n");
           goto loop;
   }
        if(i==j||i==k || i==t||j==k || j==t||k==t){
           printf("Input wrong, Please input again\n");
           goto loop;
   }
         if(get24(i,j,k,t));
         else 
			 {printf("Sorry, the four integer cannot be calculated to get 24\n");
			  goto loop;} 
 }

        此时改程序已经可以成功实现。

  • 27
    点赞
  • 121
    收藏
    觉得还不错? 一键收藏
  • 15
    评论
以下是C语言实现24点游戏的代码和解释: ```c #include <stdio.h> #include <stdlib.h> #define TARGET 24 #define EPSILON 1e-6 int dfs(double *nums, int len) { if (len == 1) { if (fabs(nums[0] - TARGET) < EPSILON) { return 1; } else { return 0; } } int i, j; double tmp[5]; for (i = 0; i < len; i++) { for (j = i + 1; j < len; j++) { int k, idx = 0; for (k = 0; k < len; k++) { if (k != i && k != j) { tmp[idx++] = nums[k]; } } tmp[idx] = nums[i] + nums[j]; if (dfs(tmp, len - 1)) { printf("%.0lf+%.0lf\n", nums[i], nums[j]); return 1; } tmp[idx] = nums[i] - nums[j]; if (dfs(tmp, len - 1)) { printf("%.0lf-%.0lf\n", nums[i], nums[j]); return 1; } tmp[idx] = nums[j] - nums[i]; if (dfs(tmp, len - 1)) { printf("%.0lf-%.0lf\n", nums[j], nums[i]); return 1; } tmp[idx] = nums[i] * nums[j]; if (dfs(tmp, len - 1)) { printf("%.0lf*%.0lf\n", nums[i], nums[j]); return 1; } if (nums[j] != 0) { tmp[idx] = nums[i] / nums[j]; if (dfs(tmp, len - 1)) { printf("%.0lf/%.0lf\n", nums[i], nums[j]); return 1; } } if (nums[i] != 0) { tmp[idx] = nums[j] / nums[i]; if (dfs(tmp, len - 1)) { printf("%.0lf/%.0lf\n", nums[j], nums[i]); return 1; } } } } return 0; } int main() { double nums[5]; int i; for (i = 0; i < 4; i++) { scanf("%lf", &nums[i]); } if (dfs(nums, 4)) { printf("Yes\n"); } else { printf("No\n"); } return 0; } ``` 代码解释: 1. 定义了目标值TARGET和一个极小值EPSILON,用于判断计算结果是否等于目标值。 2. dfs函数是本程序的核心,用于递归计算所有可能的表达式,直到只剩下一个数,判断是否等于目标值。 3. 在dfs函数中,首先判断是否只剩下一个数,如果是,则判断该数是否等于目标值,如果是,则返回1,否则返回0。 4. 如果不止一个数,则枚举所有可能的两个数的组合,计算它们的和、差、积、商,并将结果存入一个临时数组tmp中,然后递归调用dfs函数,计算剩下的数。 5. 如果递归调用的结果为1,则说明找到了一种表达式,输出该表达式,并返回1。 6. 如果所有的组合都尝试过了,仍然没有找到符合要求的表达式,则返回0。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值