算法设计思路:
穷举法就是列出4个数字加减乘除的各种可能性。首先我们将4个数设为a,b,c,d,,将其排序列出四个数的所有排序序列组合(共有A44=24种组合)。再进行符号的排列表达式,其中算术符号有+,—,,/,(,)。其中有效的表达式有a(b-c/b),ab-cd,等等。列出所有有效的表达式。其中a,b,c,d的范围是1到13。用随机函数产生四个1-13的数。要实现24点的算法,就是通过4个数字,4个运算符号和2对括号(最多为2对),通过各种组合判断其结果是否为24。我们用a,b,c,d代替4个数字。考虑每种可能,总的算法就有7种可能。
1没括号的(形如abc*d);
2有括号的(形如(a * b) * c * d);
3有括号的(形如(a * b * c) * d);
4有括号的(形如a * (b * c) * d);
5有括号的(形如(a * b) * (c * d));
6有括号的(形如((a * b) * c) * d);
7有括号的(形如(a * (b * c)) * d)。
我的程序对运算式子进行穷举,去掉等价的和无效的,最终合法表达式只有73种。
源代码:

#include<stdio.h>
#include<math.h>
#include<conio.h>
#include<string.h>
#include <stdlib.h>
#include <time.h> //用到了time函数
int treat(float a,float b,float c,float d,char *s,int *sss);
float myF(int flag,float m,float n);
void myPrint(int type,int i,int j,int k,float a,float b,float c,float d);
void my(int type,int i,int j,int k,float a,float b,float c,float d,char *s,int *sss);
int temp=0;

//发牌函数、产生四个随机数
int Deal(int *a,int *b,int *c,int *d)
{
    int i,p;
    srand(time(0));
    int q=0;
    for(i=0;i<4;i++)
    {
    p=rand()%12+1; // 产生的随机数a作为增量,范围1-10
    q=q+p;
    if(i==0)    *a=q%13+1;//a,b,c,d代表了发的四个牌
    if(i==1)    *b=q%13+1;
    if(i==2)    *c=q%13+1;
    if(i==3)    *d=q%13+1;
    }
return 0;
}



//计算正确答案的函数
int treat(float a,float b,float c,float d,char *s,int *sss)
{

    int i,j,k;
    float sum1,sum2,sum3;
    for (i=0;i<4;i++)
    for (j=0;j<6;j++)
    for (k=0;k<6;k++)
    {
        if ((!(i==3 && b==0)) && (!(j==3 && c==0)) && (!(k==3 &&
        d==0)))
        {
            sum1=myF(i,a,b);
            sum2=myF(j,sum1,c);
            sum3=myF(k,sum2,d);
            if (fabs(sum3-24)<0.1)
            {
                temp++;
                my(3,i,j,k,a,b,c,d,s,sss);//判断玩家答案正确
                myPrint(1,i,j,k,a,b,c,d);//输出正确答案
            }
        }
        if (k==2)
        {
                sum1=myF(i,a,b);
                sum2=myF(j,c,d);
                sum3=sum1*sum2;
                 if (fabs(sum3-24)<0.1)
            {
            temp++;
            my(3,i,j,k,a,b,c,d,s,sss);//判断玩家答案正确
            myPrint(2,i,j,k,a,b,c,d);//输出正确答案
            }
        }
        if (k==3)
        {
            sum1=myF(i,a,b);
            sum2=myF(j,c,d);
            if (sum2!=0)
            {
                sum3=sum1/sum2;
                if (fabs(sum3-24)<0.1)
                {
                    temp++;
                    my(3,i,j,k,a,b,c,d,s,sss);//判断玩家答案正确
                    myPrint(3,i,j,k,a,b,c,d);//输出正确答案
                }
            }
        }
    }
    if (temp==0)
    return 0;
    else
    return 1;
}

//表达式计算
float myF(int flag,float m,float n)
{

    if (flag==0)
        return (m+n);
    if (flag==1)
        return (m-n);
    if (flag==2)
        return (m*n);
    if (flag==3)
        if (n==0)
            return 30000;
    else
        return (m/n);
    if (flag==4)
        return (n-m);
    if (flag==5)
        if (m==0)
        return 30000;
    else
        return (n/m);
    return 0;
}


//判断玩家答案是否正确的函数
void my(int type,int i,int j,int k,float a,float b,float c,float d,char *s,int *sss)
{
    char sigle[6];
    char ss[20];//保存正确答案
    sigle[0]='+';
    sigle[1]='-';
    sigle[2]='*';
    sigle[3]='/';
    sigle[4]='-';
    sigle[5]='/';
    if (type==1)
    {
        if(j==4 || j==5)
        {
            if (k==4 || k==5)
            {
                sprintf(ss,"(%2.0f%c(%2.0f%c%2.0f))%c%2.0f",c,sigle[j],a,sigle[i],b,sigle[k],d);
                if(strcmp(ss,s)==0) *sss=1;//判断玩家答案是否正确
            }

            else
            {
                sprintf(ss,"(%2.0f%c(%2.0f%c%2.0f))%c%2.0f",c,sigle[j],a,sigle[i],b,sigle[k],d);
                if(strcmp(ss,s)==0) *sss=1;//判断玩家答案是否正确
            }
        }
        else if (k==4 || k==5)
        {
            sprintf(ss,"%2.0f%c((%2.0f%c%2.0f)%c%2.0f)",d,sigle[k],a,sigle[i],b,sigle[j],c);
            if(strcmp(ss,s)==0) *sss=1;//判断玩家答案是否正确
        }
        else
        {
            sprintf(ss,"((%2.0f%c%2.0f)%c%2.0f)%c%2.0f",a,sigle[i],b,sigle[j],c,sigle[k],d);
            if(strcmp(ss,s)==0) *sss=1;//判断玩家答案是否正确
        }
    }
    if (type==2 || type==3)
    {

        sprintf(ss,"(%2.0f%c%2.0f)%c(%2.0f%c%2.0f)",a,sigle[i],b,sigle[k],c,sigle[j],d);
        if(strcmp(ss,s)==0) *sss=1;//判断玩家答案是否正确
    }


}


//显示正确答案,文件保存正确答案
void myPrint(int type,int i,int j,int k,float a,float b,float c,float d)
{
    FILE *fp;
    if((fp=fopen("data.txt","a+"))==NULL)
    {
        printf("Cannot open file strike any key exit!");
        getchar();
        exit(1);
    }
    //追加方式打开文件
    char sigle[6];
    sigle[0]='+';
    sigle[1]='-';
    sigle[2]='*';
    sigle[3]='/';
    sigle[4]='-';
    sigle[5]='/';
    if (type==1)
    {
        if(j==4 || j==5)
        {
            if (k==4 || k==5)
            {
                printf("%2.0f %c (%2.0f %c (%2.0f %c %2.0f)) =24\n",d,sigle[k],c,sigle[j],a,sigle[i],b);
                fprintf(fp,"%2.0f %c (%2.0f %c (%2.0f %c %2.0f)) =24\n",d,sigle[k],c,sigle[j],a,sigle[i],b);
                //显示正确答案,文件保存正确答案
            }

            else
            {
                printf("(%2.0f %c (%2.0f %c %2.0f)) %c %2.0f =24\n",c,sigle[j],a,sigle[i],b,sigle[k],d);
                fprintf(fp,"(%2.0f %c (%2.0f %c %2.0f)) %c %2.0f =24\n",c,sigle[j],a,sigle[i],b,sigle[k],d);
                //显示正确答案,文件保存正确答案
            }
        }
        else if (k==4 || k==5)
        {
            printf("%2.0f %c ((%2.0f %c %2.0f) %c %2.0f) =24\n",d,sigle[k],a,sigle[i],b,sigle[j],c);
            fprintf(fp,"%2.0f %c ((%2.0f %c %2.0f) %c %2.0f) =24\n",d,sigle[k],a,sigle[i],b,sigle[j],c);
            //显示正确答案,文件保存正确答案
        }
        else
        {
            printf("((%2.0f %c %2.0f) %c %2.0f) %c %2.0f =24\n",a,sigle[i],b,sigle[j],c,sigle[k],d);
            fprintf(fp,"((%2.0f %c %2.0f) %c %2.0f) %c %2.0f =24\n",a,sigle[i],b,sigle[j],c,sigle[k],d);
            //显示正确答案,文件保存正确答案
        }
    }
    if (type==2 || type==3)
    {

        printf("(%2.0f %c %2.0f) %c (%2.0f %c %2.0f) =24\n",a,sigle[i],b,sigle[k],c,sigle[j],d);
        fprintf(fp,"(%2.0f %c %2.0f) %c (%2.0f %c %2.0f) =24\n",a,sigle[i],b,sigle[k],c,sigle[j],d);
        //显示正确答案,文件保存正确答案
    }
    fclose(fp);
}


//主函数,整个24点游戏的循环
int main()
{
    while(1)
    {
        FILE *fp;
        if((fp=fopen("data.txt","w"))==NULL)
        {
            printf("Cannot open file strike any key exit!");
            getchar();
            exit(1);
        }
        fclose(fp);//打开文件,清空之前记录,并检查文件是否存在
        int i,j,k,t,again,res,flag;
        float num[4];
        again=1;
        while(again==1)
        {
            i=0;
            flag=0;
            while (flag==0)
            {
                i++;
                for(i=0;i<4;i++)
                {
                    int a,b,c,d;
                    Deal(&a,&b,&c,&d);//随机发牌,产生四个数
                    if(i==0)
                    {
                        num[i]=(float)a;
                        printf ("第%d张牌%d\n",i+1,(int)num[i]);
                        //将随机发牌,产生的第一个数保存并输出
                    }
                    if(i==1)
                    {
                        num[i]=(float)b;
                        printf ("第%d张牌%d\n",i+1,(int)num[i]);
                        //将随机发牌,产生的第二个数保存并输出
                    }
                    if(i==2)
                    {
                        num[i]=(float)c;
                        printf ("第%d张牌%d\n",i+1,(int)num[i]);
                        //将随机发牌,产生的第三个数保存并输出
                    }
                    if(i==3)
                    {
                        num[i]=(float)d;
                        printf ("第%d张牌%d\n",i+1,(int)num[i]);
                        //将随机发牌,产生的第四个数保存并输出
                    }
                    if (num[i]<1 || num[i]>13 || num[i]!=int(num[i]))
                    flag++;
                }
                if(flag!=0)
                {
                    printf ("Error input again\n",i);
                    flag=0;
                }
                else
                    flag=1;
            }
            char s[20];//保存玩家输入的结果
            int sss=0;//保存玩家答案是否正确
            printf("请输入一个算式以得到24点:");
            scanf("%s",s);
            int a=0;
            while(a<2)
            {
                printf("正确答案如下:\n");
                for (i=0;i<4;i++)
                for (j=0;j<4;j++)
                if (j!=i)
                for (k=0;k<4;k++)
                if (k!=j && k!=i)
                for (t=0;t<4;t++)
                if (t!=i && t!=j && t!=k)
                {
                    res=treat(num[i],num[j],num[k],num[t],s,&sss);
                }
                if (res==0)
                    {
                        printf ("\nNo answer\n");
                        break;
                    }
                if(a==0)
                {
                    system("cls");
                    if(sss==1)
                    {
                        printf("恭喜你!您的回答正确\n");
                        a++;
                    }
                    else
                    {
                        printf("很遗憾!您的回答错误\n");
                        printf("是否显示正确答案?\n1、查看答案     2、进入下一题\n");
                        int c;
                        c=getch();
                        if(c=='1')  {}
                        else if(c=='2') {a++;}
                        else printf("按键错误!默认显示正确答案!\n");
                    }
                }
                a++;
            }
            printf("按任意键进入下一题!\n");
            getch();
            system("cls");//每玩一次清空屏幕
        }
    }
}

运行结果
24点游戏-LMLPHP

24点游戏-LMLPHP

24点游戏-LMLPHP

10-06 14:47