题意:一个数字序列和一个目标数字,看否能让这个序列经过+-×/得出目标数字答案。如果可以打印算式。
题解:只dfs会超时,加一个数组存储数字序列中每个数字与下一个数字的运算结果是否已经出现过,减少重复计算。
#include <stdio.h>
#include <string.h>
#include <math.h>
const int N = 105;
const int MAX = 65000;
int val[N], now[N][MAX], n, tar, flag;
char ope[N];
void dfs(int cur, int v) {
if (fabs(v) > 32000)
return;
if (cur == n - 1 && v == tar) {
flag = 1;
return;
}
if (cur == n - 1)
return;
if (now[cur][v])
return;
now[cur][v] = 1;
int temp = v + val[cur + 1];
ope[cur] = '+';
dfs(cur + 1, temp);
if (flag)
return;
temp = v - val[cur + 1];
ope[cur] = '-';
dfs(cur + 1, temp);
if (flag)
return;
temp = v * val[cur + 1];
ope[cur] = '*';
dfs(cur + 1, temp);
if (flag)
return;
if (val[cur + 1] && v % val[cur + 1] == 0) {
temp = v / val[cur + 1];
ope[cur] = '/';
dfs(cur + 1, temp);
}
}
int main() {
int t;
scanf("%d", &t);
while (t--) {
flag = 0;
memset(now, 0, sizeof(now));
scanf("%d", &n);
for (int i = 0; i < n; i++)
scanf("%d", &val[i]);
scanf("%d", &tar);
dfs(0, val[0]);
if (!flag)
printf("NO EXPRESSION\n");
else {
for (int i = 0; i < n - 1; i++)
printf("%d%c", val[i], ope[i]);
printf("%d=%d\n", val[n - 1], tar);
}
}
return 0;
}