现在的位置: 首页 > 综合 > 正文

24点游戏

2013年10月03日 ⁄ 综合 ⁄ 共 2687字 ⁄ 字号 评论关闭

        《编程之美》1.16是对24点游戏实现的分析。24点游戏是一款非常大众化的智力游戏,规则很简单,给出4个在1~13间的数字,通过加减乘除四则运算使四个数字的运算结果为24。现在需要编程实现求解24点游戏的表达式。

        最初没有看书中所给出的实现代码,想到的最简单最直接的方法就是穷举。这里,我们需要事先考虑到这个游戏的一些约束条件,由于加减乘除均为二元运算,每次选出两个数字进行计算,计算的结果和其他数字作为下一次求解的备选数字。同时,要注意除法运算中存在除数和被除数的区别,并且不考虑中间运算出现负值的情况(即减法运算中被减数要大于减数)。注意做除法时除数不能为0。由于只有4个数,因此递归最多会有4层嵌套。我的解法和书中提供的解法一思想是一致的,由于C中没有运算符重载等操作,C实现要稍微负载一些。相比之下,我的程序中空间开销也比较大,每次递归调用都申请了数组,这一点可以借鉴书中提供的方法。代码如下:

        书中解法二应该是一种广度优先的思想,将两个子集中的元素都进行四则运算,也有大量的冗余计算,但可以借助于之前的计算,相比解法一,它需要的空间开销要更大。

附我的C实现代码:

#include <stdio.h>

#define GAME_OK         1
#define GAME_NOT_OK     0

const double dThreshold = 1E-6;
typedef struct
{
        double  value;
        char    expression[20];
}sItem;

int Game24(sItem sArray[], int number);

int main()
{
        int i;
        int tempArray[4];
        sItem sArray[4];
        scanf("%d %d %d %d", &tempArray[0], &tempArray[1], &tempArray[2], &tempArray[3]);
        for(i = 0; i < 4; i++)
        {
                sArray[i].value = (double)tempArray[i];
                sprintf(sArray[i].expression, "%d", tempArray[i]);
        }
        if(Game24(sArray, 4) == GAME_OK)
                printf("done.\n");
        else
                printf("no answer.\n");
        return 0;
}

int Game24(sItem sArray[], int number)
{
        int i, j, k;
        sItem stempArray[number - 1];
        if(number == 1)
        {
                if(sArray[0].value > 24.0 - dThreshold && sArray[0].value < 24.0 + dThreshold)
                {
                        printf("24 = %s\n", sArray[0].expression);
                        return GAME_OK;
                }
                return GAME_NOT_OK;
        }
        for(i = 0; i < number - 1; i++)
                for(j = i + 1; j < number; j++)
                {
                        int kk = 0;
                        for(k = 0; k < number; k++)
                                if(k != i && k != j)
                                {
                                        stempArray[kk].value = sArray[k].value;
                                        sprintf(stempArray[kk].expression, "%s", sArray[k].expression);
                                        kk++;
                                }
                        stempArray[number-2].value = sArray[i].value + sArray[j].value;
                        sprintf(stempArray[number-2].expression, "(%s + %s)", sArray[i].expression, sArray[j].expression);
                        if(Game24(stempArray, number - 1) == GAME_OK)
                                return GAME_OK;
                        if(sArray[i].value > sArray[j].value)
                        {
                                stempArray[number-2].value = sArray[i].value - sArray[j].value;
                                sprintf(stempArray[number-2].expression, "(%s - %s)", sArray[i].expression, sArray[j].expression);
                        }
                        else
                        {
                                stempArray[number-2].value = sArray[j].value - sArray[i].value;
                                sprintf(stempArray[number-2].expression, "(%s - %s)", sArray[j].expression, sArray[i].expression);
                        }
                        if(Game24(stempArray, number - 1) == GAME_OK)
                                return GAME_OK;
                        stempArray[number-2].value = sArray[i].value * sArray[j].value;
                        sprintf(stempArray[number-2].expression, "%s * %s", sArray[i].expression, sArray[j].expression);
                        if(Game24(stempArray, number - 1) == GAME_OK)
                                return GAME_OK;
                        if(sArray[i].value != 0.0)
                        {
                                stempArray[number-2].value = sArray[j].value / sArray[i].value;
                                sprintf(stempArray[number-2].expression, "%s / %s", sArray[j].expression, sArray[i].expression);
                                if(Game24(stempArray, number - 1) == GAME_OK)
                                        return GAME_OK;
                        }
                        if(sArray[j].value != 0.0)
                        {
                                stempArray[number-2].value = sArray[i].value / sArray[j].value;
                                sprintf(stempArray[number-2].expression, "%s / %s", sArray[i].expression, sArray[j].expression);
                                if(Game24(stempArray, number - 1) == GAME_OK)
                                        return GAME_OK;
                        }
                }
        return GAME_NOT_OK;
}

抱歉!评论已关闭.