• 4张纸加减乘除牌求24


    昨天有个同学问我如何使用5,5,5,1这四个数加减乘除求出24,我想了很久才想出来答案。

    还记得很久以前也玩过一个类似的游戏:翻出4张纸牌牌,用加减乘除求24。

    对于这个问题,写了一个小程序解决:

    程序如下:输入4个数和1个答案,给出运算的路径。

    编程语言:C 环境:vs2012

    运行结果如下:

    关键流程如下:

    1、求出把四张牌的24种排列顺序,

    2、这24种排列中再更换中间的运算符的符号位置(4的3次方种情况)

    3、以上每一种情况再对应4种括号位置:('.'表示符号)

      1、(a.b).c).d  2、(a.(b.c).d  3、(a.b).(c.d)   4、a.(b.(c.d)  

    4、这个程序存在很多相同的情况,还有大量优化空间 比如a+b+c+d括号括哪都是一样,而且abcd位置怎么改变结果都是一样的

    列出关键算法

    1、递归求出全排列:

    //lst[]:输入数据数组

    //length:输入数据长度

    //*buf:排列存放地址

    2、输入数字与符号计算结果

    //:a,b,c,d:输入四个待运算的浮点数

    //symbol1,symbol2,symbol3:中间3个运算符的种类

    //这一段程序对应上述第1种括号情况,第2-4种情况对应函数checking2-checking4

     

    3、获得最终路径

    //a、b、c、d表示4张牌的数字,sum表示结果(算24输入24)

    //*result:输出队列的地址,每8个数为1组:1、其中一张牌的数字,2、符号,3、其中一张牌得数字,4、符号,5、其中一张牌得数字,6、符号,7、剩下一张牌得数字,8、括号的位置(对应上面提到的4种情况)

    //返回:1运算成功,0:排列的数量多于data_perm的长度

    程序清单:

    #include <stdio.h>
    #include <memory.h>
    #define NUM 4
    #define ENDFLAG 255

    #define NUMOFRESEULT 600
    unsigned char result[NUMOFRESEULT]={0};


    //计算结果
    float checking(float a,char symbol1,float b,char symbol2,float c,char symbol3,float d)
    {

    const char symbolBuf[NUM]={'+','-','*','/'};
    float temp1;
    float temp2;
    float temp3;

    if(symbol1==symbolBuf[0])
    temp1=a+b;
    else if(symbol1==symbolBuf[1])
    temp1=a-b;
    else if(symbol1==symbolBuf[2])
    temp1=a*b;
    else if(symbol1==symbolBuf[3])
    temp1=a/b;

    if(symbol2==symbolBuf[0])
    temp2=temp1+c;
    else if(symbol2==symbolBuf[1])
    temp2=temp1-c;
    else if(symbol2==symbolBuf[2])
    temp2=temp1*c;
    else if(symbol2==symbolBuf[3])
    temp2=temp1/c;

    if(symbol3==symbolBuf[0])
    temp3=temp2+d;
    else if(symbol3==symbolBuf[1])
    temp3=temp2-d;
    else if(symbol3==symbolBuf[2])
    temp3=temp2*d;
    else if(symbol3==symbolBuf[3])
    temp3=temp2/d;


    return temp3;
    }
    //先结合中间的计算结果
    float checking_2(float a,char symbol1,float b,char symbol2,float c,char symbol3,float d)
    {

    const char symbolBuf[NUM]={'+','-','*','/'};
    float temp1;
    float temp2;
    float temp3;

    if(symbol2==symbolBuf[0])
    temp1=b+c;
    else if(symbol2==symbolBuf[1])
    temp1=b-c;
    else if(symbol2==symbolBuf[2])
    temp1=b*c;
    else if(symbol2==symbolBuf[3])
    temp1=b/c;

    if(symbol1==symbolBuf[0])
    temp2=a+temp1;
    else if(symbol1==symbolBuf[1])
    temp2=a-temp1;
    else if(symbol1==symbolBuf[2])
    temp2=a*temp1;
    else if(symbol1==symbolBuf[3])
    temp2=a/temp1;

    if(symbol3==symbolBuf[0])
    temp3=temp2+d;
    else if(symbol3==symbolBuf[1])
    temp3=temp2-d;
    else if(symbol3==symbolBuf[2])
    temp3=temp2*d;
    else if(symbol3==symbolBuf[3])
    temp3=temp2/d;


    return temp3;
    }
    //先结合后边的计算结果
    float checking_3(float a,char symbol1,float b,char symbol2,float c,char symbol3,float d)
    {

    const char symbolBuf[NUM]={'+','-','*','/'};
    float temp1;
    float temp2;
    float temp3;

    if(symbol1==symbolBuf[0])
    temp1=a+b;
    else if(symbol1==symbolBuf[1])
    temp1=a-b;
    else if(symbol1==symbolBuf[2])
    temp1=a*b;
    else if(symbol1==symbolBuf[3])
    temp1=a/b;

    if(symbol3==symbolBuf[0])
    temp2=c+d;
    else if(symbol3==symbolBuf[1])
    temp2=c-d;
    else if(symbol3==symbolBuf[2])
    temp2=c*d;
    else if(symbol3==symbolBuf[3])
    temp2=c/d;

    if(symbol2==symbolBuf[0])
    temp3=temp1+temp2;
    else if(symbol2==symbolBuf[1])
    temp3=temp1-temp2;
    else if(symbol2==symbolBuf[2])
    temp3=temp1*temp2;
    else if(symbol2==symbolBuf[3])
    temp3=temp1/temp2;


    return temp3;

    }
    //结合后三个的计算结果
    float checking_4(float a,char symbol1,float b,char symbol2,float c,char symbol3,float d)
    {

    const char symbolBuf[NUM]={'+','-','*','/'};
    float temp1;
    float temp2;
    float temp3;

    if(symbol3==symbolBuf[0])
    temp1=c+d;
    else if(symbol3==symbolBuf[1])
    temp1=c-d;
    else if(symbol3==symbolBuf[2])
    temp1=c*d;
    else if(symbol3==symbolBuf[3])
    temp1=c/d;

    if(symbol2==symbolBuf[0])
    temp2=b+temp1;
    else if(symbol2==symbolBuf[1])
    temp2=b-temp1;
    else if(symbol2==symbolBuf[2])
    temp2=b*temp1;
    else if(symbol2==symbolBuf[3])
    temp2=b/temp1;

    if(symbol1==symbolBuf[0])
    temp3=a+temp2;
    else if(symbol1==symbolBuf[1])
    temp3=a-temp2;
    else if(symbol1==symbolBuf[2])
    temp3=a*temp2;
    else if(symbol1==symbolBuf[3])
    temp3=a/temp2;


    return temp3;
    }
    //交换*a和*b
    void swap(float *a,float *b)
    {
    float c;
    c=*a;
    *a=*b;
    *b=c;
    }

    //求排列
    void perm(float list[], int k, int m,float *buf,int *cnt)
    {
    int i;
    if(k > m)
    {
    for(i = 0; i <= m; i++)
    {
    // printf("%d ", list[i]);
    *(buf+(*cnt))=list[i];
    (*cnt)++;
    }
    }
    else
    {
    for(i = k; i <= m; i++)
    {
    swap(&list[k], &list[i]);
    perm(list, k + 1, m,buf,cnt);
    swap(&list[k], &list[i]);
    }
    }
    }
    //求全排
    void Permutation(float list[], int length,float *buf)
    {
    int cnt=0;
    perm(list,0,length-1,buf,&cnt);
    }
    //计算获得答案的算法
    int cal_arithmetic(unsigned char *result,int a,int b,int c,int d,int sum)
    {
    float dataIn[4];
    float data_perm[4*4*3*2*1];
    int symbol[NUM]={'+','-','*','/'};

    int i;
    int j;
    int k;
    int cnt;
    int cnt_result=0;

    //求排列
    dataIn[0]=a;
    dataIn[1]=b;
    dataIn[2]=c;
    dataIn[3]=d;
    Permutation(dataIn,4,data_perm);


    for(i=0;i<NUM;i++)
    {
    for(j=0;j<NUM;j++)
    {
    for(k=0;k<NUM;k++)
    {
    for(cnt=0;cnt<24;cnt++)
    {
    if(checking(data_perm[4*cnt],symbol[i],data_perm[4*cnt+1],symbol[j],data_perm[4*cnt+2],symbol[k],data_perm[4*cnt+3])==(float)sum)
    {
    *(result+cnt_result)=(unsigned char)data_perm[4*cnt];
    cnt_result++;
    *(result+cnt_result)=symbol[i];
    cnt_result++;
    *(result+cnt_result)=(unsigned char)data_perm[4*cnt+1];
    cnt_result++;
    *(result+cnt_result)=symbol[j];
    cnt_result++;
    *(result+cnt_result)=(unsigned char)data_perm[4*cnt+2];
    cnt_result++;
    *(result+cnt_result)=symbol[k];
    cnt_result++;
    *(result+cnt_result)=(unsigned char)data_perm[4*cnt+3];
    cnt_result++;
    *(result+cnt_result)=0;
    cnt_result++;
    }
    if(checking_2(data_perm[4*cnt],symbol[i],data_perm[4*cnt+1],symbol[j],data_perm[4*cnt+2],symbol[k],data_perm[4*cnt+3])==(float)sum)
    {
    *(result+cnt_result)=(unsigned char)data_perm[4*cnt];
    cnt_result++;
    *(result+cnt_result)=symbol[i];
    cnt_result++;
    *(result+cnt_result)=(unsigned char)data_perm[4*cnt+1];
    cnt_result++;
    *(result+cnt_result)=symbol[j];
    cnt_result++;
    *(result+cnt_result)=(unsigned char)data_perm[4*cnt+2];
    cnt_result++;
    *(result+cnt_result)=symbol[k];
    cnt_result++;
    *(result+cnt_result)=(unsigned char)data_perm[4*cnt+3];
    cnt_result++;
    *(result+cnt_result)=1;
    cnt_result++;
    }
    if(checking_3(data_perm[4*cnt],symbol[i],data_perm[4*cnt+1],symbol[j],data_perm[4*cnt+2],symbol[k],data_perm[4*cnt+3])==(float)sum)
    {
    *(result+cnt_result)=(unsigned char)data_perm[4*cnt];
    cnt_result++;
    *(result+cnt_result)=symbol[i];
    cnt_result++;
    *(result+cnt_result)=(unsigned char)data_perm[4*cnt+1];
    cnt_result++;
    *(result+cnt_result)=symbol[j];
    cnt_result++;
    *(result+cnt_result)=(unsigned char)data_perm[4*cnt+2];
    cnt_result++;
    *(result+cnt_result)=symbol[k];
    cnt_result++;
    *(result+cnt_result)=(unsigned char)data_perm[4*cnt+3];
    cnt_result++;
    *(result+cnt_result)=2;
    cnt_result++;
    }
    if(checking_4(data_perm[4*cnt],symbol[i],data_perm[4*cnt+1],symbol[j],data_perm[4*cnt+2],symbol[k],data_perm[4*cnt+3])==(float)sum)
    {
    *(result+cnt_result)=(unsigned char)data_perm[4*cnt];
    cnt_result++;
    *(result+cnt_result)=symbol[i];
    cnt_result++;
    *(result+cnt_result)=(unsigned char)data_perm[4*cnt+1];
    cnt_result++;
    *(result+cnt_result)=symbol[j];
    cnt_result++;
    *(result+cnt_result)=(unsigned char)data_perm[4*cnt+2];
    cnt_result++;
    *(result+cnt_result)=symbol[k];
    cnt_result++;
    *(result+cnt_result)=(unsigned char)data_perm[4*cnt+3];
    cnt_result++;
    *(result+cnt_result)=3;
    cnt_result++;
    }
    }
    }
    }
    }
    *(result+cnt_result)=ENDFLAG;
    return 0;

    }

    //获取数
    void getdata(int *a,int *b,int *c,int *d,int *e)
    {
    printf("请输入A:");
    scanf("%d",a);
    printf(" 请输入B:");
    scanf("%d",b);
    printf(" 请输入C:");
    scanf("%d",c);
    printf(" 请输入D:");
    scanf("%d",d);
    printf(" 请输入要计算的答案:");
    scanf("%d",e);
    }
    //输出数据
    void printfdata(void)
    {
    int i=0;

    printf(" 结果:");
    while(result[i*8]!=ENDFLAG)
    {
    if(result[i*8+7]==0)
    printf("(%d %c %d) %c %d) %c %d ",result[i*8],result[i*8+1],result[i*8+2],result[i*8+3],result[i*8+4],result[i*8+5],result[i*8+6]);
    else if(result[i*8+7]==1)
    printf("(%d %c (%d %c %d)) %c %d ",result[i*8],result[i*8+1],result[i*8+2],result[i*8+3],result[i*8+4],result[i*8+5],result[i*8+6]);
    else if(result[i*8+7]==2)
    printf("(%d %c %d) %c (%d %c %d) ",result[i*8],result[i*8+1],result[i*8+2],result[i*8+3],result[i*8+4],result[i*8+5],result[i*8+6]);
    else if(result[i*8+7]==3)
    printf("%d %c (%d %c %d %c %d) ",result[i*8],result[i*8+1],result[i*8+2],result[i*8+3],result[i*8+4],result[i*8+5],result[i*8+6]);
    i++;
    }
    }


    int main()
    {
    int input1,input2,input3,input4,input5;//获取4个输入和1个结果

    while(1)
    {
    //清零输出数组和指针
    memset((void*)result,0,NUMOFRESEULT*sizeof(result[0]));

    //获取数据和答案
    getdata(&input1,&input2,&input3,&input4,&input5);

    //寻找算法
    cal_arithmetic(result,input1,input2,input3,input4,input5);

    //打印算法
    printfdata();
    }
    }

     

  • 相关阅读:
    poj2192
    poj2002
    poj2190
    poj2001
    poj2195
    自我成长:20岁到40岁的简单人生规划
    最容易让人失恋的十种职业
    职场发展的5W问题(对我影响很大)
    你个人知识管理了吗?
    安慰人的10大原则——当不知该说什么时
  • 原文地址:https://www.cnblogs.com/HongYi-Liang/p/5676961.html
Copyright © 2020-2023  润新知