24点

来源:互联网 发布:大学生刷题软件 编辑:程序博客网 时间:2024/04/28 06:39

24点游戏是一个非常有意思的游戏,很流行,玩法很简单:给你4张牌,每张牌上有数字(其中A代表1J代表11Q代表12K代表13),你可以利用数学中的加、减、乘、除以及括号想办法得到24,例如:

((A*K)-J)*Q等价于((1*13)-11)*12=24

加减乘不用多说了,但除法必须满足能整除才能除!这样有一些是得不到24点的,所以这里只要求求出不超过24的最大值。

分析

搜索对象较复杂:1数字的顺序,2运算符号,3优先级

逐个突破

数字的顺序:全排列

运算符号:对应到34进制数

优先级:使用不同的函数搜索不同数量的数字(4个、3个、2个)

#include<stdio.h>#include<stdlib.h>#define swap(a,b) {int c=a;a=b;b=c;}#define max(a,b) (a>b?a:b)//数组a保留计算结果//op保留运算符int a[4][4], op[4];char oprater[5]="+-*/";int m;void dfs(int);//两个数相运算并保存运算结果bool numop(int,int,int,int,int,int);int main(){    int i;    char c[4][3];    for(i=0; i<4; i++)    {        scanf(" %s",&c[i]);        if(c[i][0]=='A')a[0][i]=1;        else if(c[i][0]=='J')a[0][i]=11;        else if(c[i][0]=='Q')a[0][i]=12;        else if(c[i][0]=='K')a[0][i]=13;        else if(c[i][0]=='1'&&c[i][0]=='0')            a[0][i]=10;        else a[0][i]=c[i][0]-'0';    }    dfs(0);    printf("%d\n",m);    return 0;}void dfs(int index){    int i,j,k,x,y;    if(index==3) //第三层计算结束,停止递归    {        if(a[index][0]<=24)  m=max(m,a[index][0]);//保存最优解        return;    }    for(i=0; i<4-index; i++) //两层循环用于选择两个运算数x和y        for(j=i+1; j<4-index; j++)        {            x=a[index][i];            y=a[index][j];            if(x<y)swap(x,y);            for(k=0; k<4; k++) //选取一个运算符                if(numop(k,x,y,index,i,j)&&index<4)//计算结果并进入下一层递归                    dfs(index+1);        }}//参数:运算符指针,左右操作数,递归层数,左右操作数指针bool numop(int ch, int x,int y,int index, int left,int right  ){    int *p=&a[index+1][0],i,j=1;    switch(oprater[ch])//根据选取的运算符进行运算,并保留计算结果    {    case '+':        *p=x+y;        break;    case '-':        *p=x-y;        break;    case '*':        *p=x*y;        break;    case '/':        if(!y||x%y)return false;        *p=x/y;    }    for(i=0; i<4-index&&j<3-index; i++) //复制{a}中剩余数字        if(i!=left&&i!=right)            a[index+1][j++]=a[index][i];    return true;}