24点游戏c语言程序代码,24点游戏算法(C语言实现)

一般而言,我理解的24点游戏是用4个数字经过数学运行,得到24. 一般推广版的应该使用扑克的52张牌(出去大小王),A表示1,K表示13.任意4张牌看是否能够组合得到24.

我这里所设计的就是这样的情况,而不是任意的4个数。(因为这里需要用一个办法表示分数,而我使用了比较简单的一种,能表示范围较小,所以我只处理了1到13这个情况。虽然实现里边可以将13这个范围向上推一段。)

4个数进行四则运算,一般的思维是四个数中间的3个空放置3个运算符,然后可能还需要在不同的地方加上括号,表示优先级的不同。仅仅是数字和运算符好好做,一旦要添加括号就会有点乱七八糟。前两天看网页突然看到后缀表达式这个东西,我一下想起来了。(网页作者说后缀表达式可以实现无括号的优先级运算)那我使用后缀表达式的这种方法来做就简单了。反正就只有4个数。

假设I、J、M、N是4个数,r、s、t是3个运算符。那么使用后缀表达式只有如下4种情况:

1)I J r M N s t ==> (I r J) t (M s N)

2)I J r M s N t ==> ((I r J) s M) t N

3)I J M r s N t ==> (I s (J r M)) t N

4)I J M N r s t ==> I t (J s (M r N))

不理会所有的重复,上面4种情况分别有1536中可能,那么总计就是 6144中可能情况。每种情况计算3次,也就20000次计算而已。对计算机来说这个数目是极小的。

在实现中,我没有采用任何取巧的办法,而是每种情况使用了7个for循环进行计算。唯一的取巧是前两种的前边4个for循环是一样,我就将两种拼起来了。

处理整数计算还有一个问题是,计算机无法精确的表示分数,特别是那种无限小数,比如1/3这种。如果不能精确计算,最后就无法判断是否精确等于24,这是计算机的一个弱点,这点不如人啊。

我的方法是,每个数字都用一个int表示,int表示为4字节。由于最大的单个数为13,那么即使是13的连乘也不过28561,不足两个字节能表示的65536 。因此我使用一个int的低两个字节表示分子或者实际的数值(没有分母的,也就等于整个int表示的数),高两个字节表示分母(不存在分母则表示为0)。在做计算时将分子统一为等分母的数,然后计算之后与分母作用得到最后的数。这样的话4/5就表示为了0x00050004了。

由于找到一种解法就结束,所以根据输入的数据,得到的可能与通常人们计算得到的结果有出入,比如2 2 6 6 ,人的计算结果一般为2*6+2*6,但是程序结果可能为(2+6)*(6/2),当然结果也是正确的。

另外需要注意的是,对于任何两个数计算得到负数,我都没有继续啊向下计算,因为这个必须得加一个正数或者乘以一个辅助才可能得到24 。而既然能够得到负数,两个数的位置调换一下就是一个正数了,没有必要在数值前边加上负号来处理。

具体实现代码如下,c语言实现:

* 24.c 计算4个1到13之间的数(包含)是否能够通过加减乘除达到24.*/

#include

#define MASK 0xFFFF

#define SHIFT 16

enum {FAILURE = 0, SUCCESS};

const char ops[] = "+*-/";

int test (const int nums[], char *result);

int calculate (int num1, int num2, char op);

int main(int argc, char * argv[])

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
24点游戏是一种非常有趣的数学游戏,它可以极大地锻炼我们的大脑思维能力,并且也可以培养我们的团队协作精神。当然,除了玩游戏,我们也可以通过实现24点游戏算法,来学习和巩固C语言代码编写的能力。 24点游戏算法实现主要包含以下几个步骤: 1. 生成所有4个数字的排列组合,并存储在数组中。 2. 对于所有的排列组合,分别进行四则运算,并计算出结果。 3. 判断计算出的结果是否等于24,如果等于,则输出该组合。 4. 如果没有任何一组排列组合的计算结果等于24,则输出“无解”。 下面是C语言实现的代码: #include <stdio.h> #include <stdlib.h> int main() { int a, b, c, d; //4个数字 int i, j, k; int count = 0; //计数器 printf("请输入4个数字(1 ~ 13):\n"); scanf("%d %d %d %d", &a, &b, &c, &d); int arr[4] = {a, b, c, d}; //将4个数字存储在数组中 int op[3]; //运算符数组,长度为3,分别代表两个运算符和括号 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; op[0] = op[1] = op[2] = -1; //初始化 op[2] = 0; //括号位置 calculate(arr[i], arr[j], arr[k], arr[6-i-j-k], op, &count); } } } if (count == 0) { printf("无解!\n"); } return 0; } void calculate(int a, int b, int c, int d, int op[], int *count) { int result; if (op[0] != -1) { if (op[2] == 0) { int tmp1 = calculate2(a, b, op[0]); result = calculate2(tmp1, c, op[1]); result = calculate2(result, d, op[2]); if (result == 24) { printf("%d %c %d %c %d %c %d = 24\n", a, get_operator(op[0]), b, get_operator(op[1]), c, get_operator(op[2]), d); (*count)++; } return; } else { int tmp1 = calculate2(a, b, op[0]); int tmp2 = calculate2(c, d, op[1]); result = calculate2(tmp1, tmp2, op[2]); if (result == 24) { printf("(%d %c %d) %c (%d %c %d) = 24\n", a, get_operator(op[0]), b, get_operator(op[2]), c, get_operator(op[1]), d); (*count)++; } return; } } else { calculate(a, b, c, d, &op[0], count); calculate(a, b, d, c, &op[0], count); calculate(a, c, b, d, &op[0], count); calculate(a, c, d, b, &op[0], count); calculate(a, d, b, c, &op[0], count); calculate(a, d, c, b, &op[0], count); calculate(b, a, c, d, &op[0], count); calculate(b, a, d, c, &op[0], count); calculate(b, c, a, d, &op[0], count); calculate(b, c, d, a, &op[0], count); calculate(b, d, a, c, &op[0], count); calculate(b, d, c, a, &op[0], count); calculate(c, a, b, d, &op[0], count); calculate(c, a, d, b, &op[0], count); calculate(c, b, a, d, &op[0], count); calculate(c, b, d, a, &op[0], count); calculate(c, d, a, b, &op[0], count); calculate(c, d, b, a, &op[0], count); calculate(d, a, b, c, &op[0], count); calculate(d, a, c, b, &op[0], count); calculate(d, b, a, c, &op[0], count); calculate(d, b, c, a, &op[0], count); calculate(d, c, a, b, &op[0], count); calculate(d, c, b, a, &op[0], count); } } int calculate2(int a, int b, int op) { switch (op) { case 0: return a + b; case 1: return a - b; case 2: return a * b; case 3: return a / b; } return 0; } char get_operator(int op) { switch (op) { case 0: return '+'; case 1: return '-'; case 2: return '*'; case 3: return '/'; } return '?'; } 在上面的代码中,calculate函数是算法的核心部分,它采用递归的方式生成所有的排列组合,并调用calculate2函数进行四则运算。calculate2函数接受两个数字和运算符,根据运算符进行运算并返回运算结果。get_operator函数用于将运算符转化为字符表示,方便输出。运行完程序后,输出得到的结果,最后如果没有任何一组排列组合的计算结果等于24,则输出“无解”。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值