算法-给四张扑克牌,可以任意排序,加入加减乘除和括号,使得它们的运算结果是24。这个问题怎么解,如果编程又怎么解
比如给8,8,10,3 有 (8*10-8)/3 = 24
可以先不考虑大小王的情况,J表示11,以此类推。先说是否能使得运算结果为24,如果能,请给出运算表达式。如果编程求解,请注意尽量减少重复运算。求大神指点
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
可以采用分治的思想。
假设4张扑克牌组成集合为A={a,b,c,d},先将A划分为两个子集B和(A-B),其中B是A的非空真子集。然后分别计算B和(A-B)中的元素进行四则混合运算所能得到的结果集合,即f(B)和f(A-B),然后对f(B)和f(A-B)这两个集合中的元素进行加减乘除运算,最后得到所有集合的并集就是f(A)。而对B和(A-B)的计算同样采用分治思想进行计算。这样最终就可以计算出f(A)了。
而如何减少重复,其实可以在计算的过程中,把已经计算的结果保存下来,例如,在某一次计算中算出了f({3,4})的值,那么在另外一种情况下,如果也要计算f({3,4})的值,就直接把值拿过来就OK了,不用再计算了。这样就可以在一定程度上防止重复的计算。
98年的时候,教我们C程序的老师给我一个代码,递归解决。遍历出所有的组合即可。说不定我还能找到这个小程序呢,呵呵
感觉递归是无法避免的,理想的总是跟现实有些差距。
不过,24点需要的系统开销并不是很大,所以,这一点上可以放心的去递归
总结了下网络上各种操作,详见一下 cpp 程序
//============================================================================
// Name : dummy.cpp
// Author : Neo
// Version :
// Copyright : NEO's Edtion is Okay~
// Description : Hello World in C++, Ansi-style
//============================================================================
#include <iostream>
#include <stdio.h>
#include <string>
#include <cmath>
using namespace std;
const double PRECISION = 1E-6;
const int COUNT = 4;
const int RESULT = 24;
double number[COUNT];
string expression[COUNT];
bool start(int n)
{
if (1 == n)
{
if (fabs(number[0] - RESULT) < PRECISION)
{
for (unsigned int i = 1; i < expression[0].length() - 1; i++)
{
cout << expression[0][i];
}
cout << endl;
return true;
}
else
return false;
}
for (int i = 0; i < n; i++)
{
for (int j = i + 1; j < n; j++)
{
double a, b;
string expa, expb;
a = number[i];
b = number[j];
number[j] = number[n - 1];
expa = expression[i];
expb = expression[j];
expression[j] = expression[n - 1];
expression[i] = '(' + expa + '+' + expb + ')';
number[i] = a + b;
if (start(n - 1))
return true;
expression[i] = '(' + expa + '-' + expb + ')';
number[i] = a - b;
if (start(n - 1))
return true;
expression[i] = '(' + expb + '-' + expa + ')';
number[i] = b - a;
if (start(n - 1))
return true;
expression[i] = '(' + expa + '*' + expb + ')';
number[i] = a * b;
if (start(n - 1))
return true;
if (b != 0)
{
expression[i] = '(' + expa + '/' + expb + ')';
number[i] = a / b;
if (start(n - 1))
return true;
}
if (a != 0)
{
expression[i] = '(' + expb + '/' + expa + ')';
number[i] = b / a;
if (start(n - 1))
return true;
}
number[i] = a;
number[j] = b;
expression[i] = expa;
expression[j] = expb;
}
}
return false;
}
int main(void)
{
for (int i = 0; i < COUNT; i++)
{
char buffer[20];
int x;
cin >> x;
number[i] = x;
sprintf(buffer, "%d", x);
expression[i] = buffer;
}
if (start(COUNT))
{
cout << "Success" << endl;
return 0;
}
else
{
cout << "Fail" << endl;
return -1;
}
}
下面的链接有详尽的算法说明,就不复制粘贴了
http://blog.csdn.net/hackbuteer1/article/details/6712385
祝好,
斑驳敬上