游戏规则: 一副牌中去掉大小王,在剩下的52张牌中任意取四张。使用四则运算,使其最后结果为24.其中每张牌只能使用一次且A=1,J=11,Q=12,K=13。
譬如 2,4,6,8 ------> 结果为 6/(4-2)*8=24;
算法思考: 首先,从宏观上说,这种问题都是遍历穷举。再看看运算符,其中+,* 都是没有顺序的。即(a*b=b*a), 但是 -、/ 是有顺序的。那么假设都有顺序的。那么就可以统一处理了(最多效率低点,先解决问题。再考虑优化)。那么遍历所有a,b,c,d 以及 三次运算 。即A(4,4) *4*4*4 就是该算法的复杂度。(事实证明我错了。后面会讲到。)
微观上,由于中间有除法,那么不能用int类型来储存数据了。需要用double或者float.每次运算都只有两个数运算。
24点游戏编程具体算法思想可以参考《编程之美》,下面给出自己根据文中算法改写的C语言算法:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
const double Threshold = 1E-6;
#define CardsNumber 4
const int ResultValue = 24;
double NumberCard[CardsNumber];
char *result[CardsNumber];
char *oprate(char *expa,char *expb,char op)
{
//char *c=r;
char *c=(char *)malloc(sizeof(char)*50);
char *b="(";
char *a=")";
strcpy(c,b);
strcat(c,expa);
strcat(c,&op);
strcat(c,expb);
strcat(c,a);
return c;
}
int PointGame(int n)
{
int i,j,k;
double a,b;
char expa[50]={'0'};
char expb[50]={'0'};
char op;
if (n == 1)
{
if (fabs(NumberCard[0]-ResultValue) < Threshold)
{
printf("%s\n",result[0]);
return -1;
}
else
{
return 0;
}
}
else
{
for (i = 0;i < n;i++)
{
for (j = i+1;j < n;j++)
{
a = NumberCard[i];
b = NumberCard[j];
NumberCard[j] = NumberCard[n-1];
/* 因为需要删去两个已经进行过运算的数,所以在此利用NumberCard[i]保存运算结果,
利用NumberCard[j]保存最后一个数
*/
for (k=0;k<strlen(result[i]);k++)
{
expa[k]=result[i][k];
}
expa[k]='\0';
for (k=0;k<strlen(result[j]);k++)
{
expb[k]=result[j][k];
}
expb[k]='\0';
strcpy(result[j],result[n-1]);
op = '+';
result[i]=oprate(expa,expb,op);
NumberCard[i] = a+b;
if (PointGame(n-1))
return -1;
op = '-';
result[i]=oprate(expa,expb,op);
NumberCard[i] = a-b;
if (PointGame(n-1))
return -1;
op = '-';
result[i]=oprate(expb,expa,op);
NumberCard[i] = b-a;
if (PointGame(n-1))
return -1;
op = '*';
result[i]=oprate(expa,expb,op);
NumberCard[i] = a*b;
if (PointGame(n-1))
return -1;
if (b != 0)
{
op = '/';
result[i]=oprate(expa,expb,op);
NumberCard[i] = a/b;
if (PointGame(n-1))
return -1;
}
if (a != 0)
{
op = '/';
result[i]=oprate(expb,expa,op);
NumberCard[i] = b/a;
if (PointGame(n-1))
return -1;
}
NumberCard[i] = a;
NumberCard[j] = b;
strcpy(result[i],expa);
strcpy(result[j],expb);
}
}
}
return 0;
}
int main()
{
int x;
int i;
char buffer[4][100]={'0'};
for (i = 0;i < CardsNumber;i++)
{
printf("the %d number:\n",i);
scanf("%d",&x);
NumberCard[i]=x;
itoa(x,buffer[i],10);
result[i]=buffer[i];
}
i=PointGame(CardsNumber);
if (i!=0)
{
printf("Success!\n");
}
else
{
printf("Fail\n");
}
system("pause");
return 0;
}