24点
来源:互联网 发布:大学生刷题软件 编辑:程序博客网 时间:2024/04/28 06:39
24点游戏是一个非常有意思的游戏,很流行,玩法很简单:给你4张牌,每张牌上有数字(其中A代表1,J代表11,Q代表12,K代表13),你可以利用数学中的加、减、乘、除以及括号想办法得到24,例如:
((A*K)-J)*Q等价于((1*13)-11)*12=24
加减乘不用多说了,但除法必须满足能整除才能除!这样有一些是得不到24点的,所以这里只要求求出不超过24的最大值。
分析
搜索对象较复杂:1数字的顺序,2运算符号,3优先级
逐个突破
数字的顺序:全排列
运算符号:对应到3位4进制数
优先级:使用不同的函数搜索不同数量的数字(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;}