题目大意:给出一系列的数字,在给出一个目标值,要求用+,-,*,/这四种运算符算出目标值并输出表达式,/运算符只有在余数为0时才可以使用
解体思路:暴力DFS破解,通过剪枝来节省时间
1.数的范围要在-32000,32000之间
2.用vis[cur][sum]判断该值的和是否出现过
#include<cstdio>
#include<cstring>
int vis[200][65000];
int num[1000];
int target;
int n;
bool flag;
char sign[1000];
void dfs(int cur, int sum) {
if(cur == n) {
if(sum == target)
flag = true;
return ;
}
if(sum < -32000 || sum > 32000)
return ;
int temp;
temp = sum + num[cur];
if(temp >= -32000 && temp <= 32000 && !vis[cur][temp+32000]) {
vis[cur][temp+32000] = 1;
sign[cur-1] = '+';
dfs(cur+1,temp);
if(flag)
return ;
}
temp = sum - num[cur];
if(temp >= -32000 && temp <= 32000 && !vis[cur][temp+32000]) {
vis[cur][temp+32000] = 1;
sign[cur-1] = '-';
dfs(cur+1,temp);
if(flag)
return ;
}
temp = sum * num[cur];
if(temp >= -32000 && temp <= 32000 && !vis[cur][temp+32000]) {
vis[cur][temp+32000] = 1;
sign[cur-1] = '*';
dfs(cur+1,temp);
if(flag)
return ;
}
if(sum % num[cur] == 0) {
temp = sum / num[cur];
if(temp >= -32000 && temp <= 32000 && !vis[cur][temp+32000]) {
vis[cur][temp+32000] = 1;
sign[cur-1] = '/';
dfs(cur+1,temp);
if(flag)
return ;
}
}
return ;
}
int main() {
int test;
scanf("%d", &test);
while(test--) {
scanf("%d",&n);
flag = false;
memset(vis,0,sizeof(vis));
for(int i = 0; i < n; i++)
scanf("%d", &num[i]);
scanf("%d",&target);
dfs(1,num[0]);
if(!flag)
printf("NO EXPRESSION\n");
else {
for(int i = 0; i < n - 1; i++) {
printf("%d",num[i]);
printf("%c",sign[i]);
}
printf("%d=%d\n",num[n-1],target);
}
}
return 0;
}