UVA - 10400 Game Show Math

题目大意:给出n个数值,可以任意的在数值之间添加+,- ,*  ,/,运算,要求找到一个算式可以使得算式的值等于目标值。

注意:1、算式的运算符没有优先级,都是从左到右结合。

2、数值之间的位置不能更换,也就是说数值的顺序是确定的,只能修改运算符。

3、运算的过程中不能出现运算值的绝对值大于 32000 的。


解题思路:用记忆化搜索, 记录住当前前n个数字通过任意的运算所的到的 sum, 如果这个sum被判定为不能达成目标, 那么另外一种不同的运算方式使得前 n 个的 sum 等于前面判定过的,那么剪掉这条枝,因为它已经不可能到达了。


#include <cstdio>
#include <cstring>

int n, target, num[105], vis[105][64005], rec[105];
char str[5]= {"+-*/"};

bool DFS(int deep, int sum) { 
	if (deep == n) {
		if (sum == target)
			return true;
		return false;
	}

	int temp;
	for (int i = 0; i < 4; i++) {
		switch (i) {
			case 0: temp = sum + num[deep]; break;
			case 1: temp = sum - num[deep]; break;
			case 2: temp = sum * num[deep]; break;
			case 3: temp = sum / num[deep]; break;
		}
		if (temp > 32000 || temp < -32000 || vis[deep][temp + 32000])
			continue;

		vis[deep][temp + 32000] = true;

		if (DFS(deep + 1, temp)) {
			rec[deep - 1] = str[i];
			return true;
		}
	}
	return false;
}

int main() {
	int T;
	scanf("%d", &T);

	while (T--) {
		memset(vis, 0, sizeof(vis));

		scanf("%d", &n);
		for (int i = 0; i < n; i++)
			scanf("%d", &num[i]);
		scanf("%d", &target);

		if (DFS(1, num[0])) {
			for (int i = 0; i < n - 1; i++)
				printf("%d%c", num[i], rec[i]);
			printf("%d=%d\n", num[n - 1], target);
		}
		else
			printf("NO EXPRESSION\n");
	}
	return 0;
}


你可能感兴趣的:(UVA - 10400 Game Show Math)