题目链接在此
转自于这位大神
有点类似于24点。
<span style="font-size:18px;"><span style="white-space:pre"> </span>本题的思路为每次在5个数中选择2个数,然后对其分别进行加减乘除运算。
<span style="white-space:pre"> </span>在进行了每种运算之后,得到一个数,用这个数覆盖掉所选的2个数中的其中一个,由于之后的深度优先搜索的数组大小减1,且需扫描可用的数来确定最大数或者是否达到目标数,所以该其中一个为i,而不能是j,因为如果是j的话,会出现n-1的情况使得该运算结果等下不可用的情况。
<span style="white-space:pre"> </span>另外一个数用当前数组最后一个数覆盖,使数的个数减一然后进行深度优先搜寻,构建深度优先搜索树,继续进行以上运算直到计算得到目标数,或者只剩下一个数不能继续进行运算为止。 </span>
<span style="font-size:14px;">#include <iostream>
using namespace std;
int target;
int a[5];
int max_r;</span>
<span style="font-size:14px;">
void DFS(int n) {
//扫描当前可用数组,其中包含上一步骤的运算结果在内
//确定当前数组最大数
for (int i = 0; i < n; i++) {
if (a[i] <= target && a[i] > max_r) {
max_r = a[i];
}
}
//如果达到了目标数,直接返回
if (max_r == target) {
return;
}
//如果数组大小为1,不能继续进行运算了,此时max_r等于该5个数进行运算
//得到的小于目标数的最大数
if (n == 1) {
return;
}
//从n个数中任意选择两个数进行4种运算,其中通过两重循环,包含了所有可能的两个数的情况
for (int i = 0; i < n; i++) {
for (int j = i+1; j < n; j++) {
int a1 = a[i];
int a2 = a[j];
//覆盖掉已经选择了的两个数i,j,从而继续对其他数(包括刚刚计算得到的运算结果)
//进行深度优先搜索
a[j] = a[n-1];
a[i] = a1 + a2;
DFS(n-1);
a[i] = a1 - a2;
DFS(n-1);
a[i] = a2 - a1;
DFS(n-1);
a[i] = a1 * a2;
DFS(n-1);
if (a2 != 0 && a1 % a2 == 0) {
a[i] = a1 / a2;
} else if (a1 != 0 && a2 % a1 == 0) {
a[i] = a2 / a1;
}
DFS(n-1);
//运算完后,使得i,j变回原来的数,以便进行下一轮循环
a[i] = a1;
a[j] = a2;
}
}
}
int main() {
int test;
cin >> test;
while (test-- > 0) {
int value;
for (int i = 0; i < 5; i++) {
cin >> value;
a[i] = value;
}
cin >> target;
max_r = -100000000;
DFS(5);
cout << max_r << endl;
}
return 0;
}</span>