1) 将4个整数放入数组中,
(2) 在数组中取两个数字的排列,共有 P(4,2) 种排列。对每一个排列,
(2.1) 对 + - * / 每一个运算符,
(2.1.1) 根据此排列的两个数字和运算符,计算结果,
(2.1.2) 改表数组:将此排列的变两个数字从数组中去除掉,将 2.1.1 计算的结果放入数组中,
(2.1.3) 对新的数组,重复步骤 2,
(2.1.4) 恢复数组:将此排列的两个数字加入数组中,将 2.1.1 计算的结果从数组中去除掉。
(2) 在数组中取两个数字的排列,共有 P(4,2) 种排列。对每一个排列,
(2.1) 对 + - * / 每一个运算符,
(2.1.1) 根据此排列的两个数字和运算符,计算结果,
(2.1.2) 改表数组:将此排列的变两个数字从数组中去除掉,将 2.1.1 计算的结果放入数组中,
(2.1.3) 对新的数组,重复步骤 2,
(2.1.4) 恢复数组:将此排列的两个数字加入数组中,将 2.1.1 计算的结果从数组中去除掉。
可以看出,步骤2是一个递归函数。当数组中只剩下一个数字的时候,这就是表达式的最终结果,此时递归结束。这个算法使用回溯来实现,事实上它可以非常容易地推广到N个数字
#include <iostream>
#include <cmath>
using namespace std;
double const PRECISION = 1e-6; // 精度
const int n = 4; // 输入数字的个数
bool Search(int n, double* number)
{
if (n == 1)
{
if (fabs(number[0] - 24) < PRECISION)
return true;
else
return false;
}
for (int i = 0; i < n; i++)
{
for (int j = i + 1; j < n; j++) // 共 p(n,2)种排列
{
double a, b;
// 现场临时保存
a = number[i];
b = number[j];
number[j] = number[n - 1];/*
每次嵌套会丢失最后一位。数组第一位保存运算值,第二位存最后一位*/
number[i] = a + b;
if(Search(n - 1, number)) return true;
number[i] = a - b;
if (Search(n - 1, number)) return true;
number[i] = b - a;
if (Search(n - 1, number)) return true;
number[i] = a * b;
if (Search(n - 1, number)) return true;
if (b != 0) // 除数不为0
{
number[i] = a / b;
if (Search(n - 1, number)) return true;
}
if (a != 0)
{
number[i] = b / a;
if (Search(n - 1, number)) return true;
}
// 现场恢复 该排列不符合
number[i] = a;
number[j] = b;
}
}
return false;
}
bool Game24Points(int a, int b, int c, int d)
{
double num[n] = { a, b, c, d };
return Search(n, num);
}
int main()
{
int a,b,c,d;
cin>>a>>b>>c>>d;
if(Game24Points(a, b, c, d))
cout << "true" << endl;
else
cout << "false" << endl;
return 0;
}