给4个数,范围1~13之间,允许有相同的数,采用加减乘除,括号运算,并且允许中间运算有小数,每个数使用一次,构造表达式,使其结果为24,例如,输入 11,8,3,5 输出 (11-8)*(3+5)=24
解法一,穷举(在OJ平台上用这个方法时,居然出现WA,还有就是有另一种方法,暂时还没学习,学了后再添加上来)
//f(array)
//{
// if(array.length<2)
// {
// if(得到的结果为24) 输出
// else 无法构造符合要求的表达式
// }
// foreach(从数组任取两个数的组合)
// {
// foreach(运算符 + -*/ )
// {
// 1.计算该组合在此运算符下的结果
// 2.将该组合中的两个数从原数组移除,并将步骤1的计算结果放入数组
// 3.对新数组递归调用f,如果找到一个表达式则返回
// 4.将步骤1的计算结果移除,并将该组合中的两个数重新放回数组中对应的位置
// }
//
// }
#include<iostream>
#include<string>
using namespace std;
const double Threshold = 1E-6;
const int CardsNumber = 4;
const int ResultValue = 24;
double number[CardsNumber];
string result[CardsNumber];
bool PointsGame(int n)
{
if(n == 1)
{
if(fabs(number[0] - ResultValue) < Threshold)
{
cout << result[0] << 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 = result[i];
expb = result[j];
result[j] = result[n - 1];
result[i] = '(' + expa + '+' + expb + ')';
number[i] = a + b;
if(PointsGame(n - 1))
return true;
result[i] = '(' + expa + '-' + expb + ')';
number[i] = a - b;
if(PointsGame(n - 1))
return true;
result[i] = '(' + expb + '-' + expa + ')';
number[i] = b - a;
if(PointsGame(n - 1))
return true;
result[i] = '(' + expa + '*' + expb + ')';
number[i] = a * b;
if(PointsGame(n - 1))
return true;
if(b != 0)
{
result[i] = '(' + expa + '/' + expb + ')';
number[i] = a / b;
if(PointsGame(n - 1))
return true;
}
if(a != 0)
{
result[i] = '(' + expb + '/' + expa + ')';
number[i] = b / a;
if(PointsGame(n - 1))
return true;
}
number[i] = a;
number[j] = b;
result[i] = expa;
result[j] = expb;
}
}
return false;
}
int main()
{
int x;
for(int i = 0; i < CardsNumber; ++i)
{
char buffer[20];
cout << "the " << i << "th number:";
cin >> x;
number[i] = x;
_itoa_s(x, buffer, 10);
result[i] = buffer;
}
if(PointsGame(CardsNumber))
cout << "yes" << endl;
else
cout << "no" << endl;
return 0;
}