您的位置:首页 > 其它

uva10400 - Game Show Math(回溯+剪枝)

2014-07-25 16:28 357 查看
题目:uva10400 - Game Show Math(回溯+剪枝)

题目大意:给出N个数,并且给出一个目标数值,要求用上面的数字(全部),并且顺序不能乱,然后用+-*/这些操作,问最终能不能得到目标数值。这里要注意给出的数会在【-32000,32000】之间, 并且要用除法的时候,只有在能整除的时候才能用。并且中间计算结果不能超过【-32000,32000】范围。如果超过这个操作不能做。

解题思路:回溯加剪枝,将每一层计算的结果都保存下来,如果在同一层发现值出现过,并且之前计算发现这样往后是得不到目标值的,那么就可以直接剪掉。

这题题意没有读清楚,结果WA了好多遍。

代码:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

const int N = 105;
const int M = 70000;
const int maxn = 32000;

char op
;
int num
;
int n;
int target;
int flag;
char OP[4] = {'*', '-', '+', '/'};
int vis
[M];

void dfs (int k, int sum) {

if (k == n - 1) {

/*	for (int i = 0; i < n - 1; i++)
printf ("%c ", op[i]);
printf ("\n");
printf ("%d\n", sum);*/
if (sum == target)
flag = 1;
return;
}

int temp;
for (int i = 0; i < 4; i++) {

op[k] = OP[i];
switch (OP[i]) {

case '+' : temp = sum + num[k + 1];
if (abs (temp) > maxn)
break;
if (vis[k][temp + maxn])
break;
dfs (k + 1, temp); break;
case '-' : temp = sum - num[k + 1];
if (abs (temp) > maxn)
break;
if (vis[k][temp + maxn])
break;
dfs (k + 1, temp); break;
case '/' : if (sum % num[k + 1] == 0) {

temp = sum / num[k + 1];
if (abs (temp) > maxn)
break;
if (vis[k][temp + maxn])
break;
dfs (k + 1, temp);
}
break;
case '*' : temp = sum * num[k + 1];
if (abs (temp) > maxn)
break;
if (vis[k][temp + maxn])
break;
dfs (k + 1, temp); break;
}
if (flag)
return;
else if (abs (temp) <= maxn && !vis[k][temp + maxn])
vis[k][temp + maxn] = 1;
}
}

int main () {

int t;
scanf ("%d", &t);
while (t--) {

scanf ("%d", &n);
for (int i = 0; i < n; i++)
scanf ("%d", &num[i]);
scanf ("%d", &target);
flag = 0;
memset (vis, 0, sizeof (vis));
dfs(0, num[0]);
//		printf("%d\n", flag);
if (!flag)
printf ("NO EXPRESSION\n");
else {

for (int i = 0; i < n; i++) {

if (i == n - 1)
printf ("%d=%d\n", num[i], target);
else
printf ("%d%c", num[i], op[i]);
}
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: