“24点游戏是一种使用扑克牌来进行的益智类游戏,游戏内容是:从一副扑克牌中抽去大小王剩下52张,任意抽取4张牌,把牌面上的数(A代表1)运用加、减、乘、除和括号进行运算得出24。每张牌都必须使用一次,但不能重复使用。
有些组合有不同种算法,例如要用2,4,6,12四张牌组合成24点,可以有如下几种组合方法:
2 + 4 + 6 + 12 = 24
4 × 6 ÷ 2 + 12 = 24
12 ÷ 4 × (6 + 2) = 24
当然,也有些组合算不出24,如1、1、1、1 和 6、7、8、8等组合。”
–题目描述来自wikipedia:http://zh.wikipedia.org/wiki/24%E7%82%B9。
解题思路:给出a,b,c,d的所有排列情况,即4!=24种情况,对于每种序列分别用+,-,*,/来插入到两个数字之间,然而括号可以通过计算的先后顺序来实现。同时,算法采用结果导向的思路。例如:计算(a+b*d)/c的结果,假设其结果满足result = 24,则处理顺序为:
1.result = result *c;
2.result = result – a;
3.result = (result *c – a;
4.reult = result /d;
5.result = result -b;
如果result = 0,则结果满足条件。当然为了处理分数情况,分别用child,parent来表示result的分子与分母。其中加法减法–分子变分母不变,会通分;乘法除法–分子分母可能都变。
源代码如下:
//判定序列{a,b,c,d}是否满足24游戏
int can24(int a[],int n,int j,int child,int parent)
{
if(j < 0 )
{
if(child == 0)
{
return 1;
}
else
{
return 0;
}
}
for(int i = 0;i < n;i++)
{
if(i == 0)
{
child -= parent * a[j];
can24(a,n,j-1,child,parent);
child += parent * a[j];
}
else if(i == 1)
{
child += parent * a[j];
can24(a,n,j-1,child,parent);
child -= parent * a[j];
}
else if(i == 2)
{
parent *= a[j];
can24(a,n,j-1,child,parent);
parent /= a[j];
}
else if(i == 3)
{
child *= a[j];
can24(a,n,j-1,child,parent);
child /= a[j];
}
}
return 0;
}
//利用排列组合思想将每个排列进行一次判断。
void permutation24(int a[],int n,int k)
{
int i = 0;
if(n == k)
{
int child = 24;
int parent = 1;
can24(a,n,n-1,child,parent);
}
else
{
for(i = k; i < n;i++)
{
swap(a,k,i);
permutation24(a,n,k+1);
swap(a,i,k);
}
}
}
int main()
{
int b[] = {1,1,1,10};//no
int c[] = {1,2,4,7};//ok
int d[] = {5,5,5,1};//ok
if(permutation24(c,4,0))
{
cout<<"OK"<<endl;
}
else
{
cout<<"NO"<<endl;
}
return 0;
}
可能想法有点复杂,还需要继续改进。