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

题目: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[N];
int num[N];
int n;
int target;
int flag;
char OP[4] = {'*', '-', '+', '/'};
int vis[N][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;
}

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

时间: 2024-11-05 21:56:28

uva10400 - Game Show Math(回溯+剪枝)的相关文章

UVA10317- Equating Equations(回溯+剪枝)

题目链接 题意:给出一个式子,但这个式子不一定是等式,在'+','-'符号位置不变的情况下,重新排列数字的位置,使其成为等式,如果可以的话,输出其中一种排列方式. 思路:我们将等号右边的数全部移动到等号右边,例如a+b-c=d-e,移动后变成a+b+e-(c+d)=0,也就是a+b+e=c+d,所以当式子可以变化成等式时,所有数的和必然是偶数.那么问题可以转化为在n个数中找出m个数(m的值为等号左边的整数的数量),使m个 数的和为从和的一半. #include <iostream> #incl

HDU1016 Prime Ring Problem (回溯 + 剪枝)

题意: 给你一个数字N(N <= 20),要求你把这N个数组成一个环,环内的数字不能重复,左右相邻的两个的和是素数.给出最后的答案. 思路: 利用回溯剪枝算法,N个数,每个数有N种状态,枚举这N个状态,枚举过程中剪枝优化. 代码: #include <cstdio> #include <iostream> #include <cstring> #include <cstring> #include <cmath> #include <

HDU1010 Tempter of the Bone(回溯 + 剪枝)

题意: 输入一个 N * M的迷宫,这个迷宫里'S'代表小狗的位置,'X'代表陷阱,‘D’代表门,‘.’代表可行走的地方,小狗每次可以选择往周围的四个方向行走,问这个小狗能否正好T步找到门. 思路: 利用回溯 + 剪枝,这道题剪枝特别重要. 剪枝一: 可以把图看成这样: 1 0 1 0 10 1 0 1 01 0 1 0 10 1 0 1 01 0 1 0 1 则假设从点 a(i + j,横纵坐标之和) 走到点 b(i + j) ,如果 a 和 b 的奇偶性相同,那么从 a 到 b 必须是偶数步

[算法专题] 深度优先搜索&amp;回溯剪枝

1. Palindrome Partitioning https://leetcode.com/problems/palindrome-partitioning/ Given a string s, partition s such that every substring of the partition is a palindrome. Return all possible palindrome partitioning of s. For example, given s = "aab&

uva 307 Sticks(回溯剪枝)

uva 307 Sticks George took sticks of the same length and cut them randomly until all parts became at most 50 units long. Now he wants to return sticks to the original state, but he forgot how many sticks he had originally and how long they were origi

7.5 深搜-最佳调度问题(枚举排列+回溯+剪枝)

这几天偷了几天懒,今天为大家讲解一篇深搜好题,典型的全排列问题需运用剪枝+回溯来优化运行时间,与上一道都是比较典型的深搜优化问题. 题目描述 假设有n个任务由k个可并行工作的机器完成,完成任务i需要的时间为ti,对任意给定的整数n和k,以及完成任务i需要的时间ti,设计一个算法,求完成这n个任务的最佳调度,使得完成全部任务的时间最早. 输入 第一行有2个正整数n和k,第二行有n个正整数,表示ti n<7000,c<maxlongin 输出 一个整数,输出最早时间 样例输入 7 3 2 14 4

HDU-4848 Wow! Such Conquering! (回溯+剪枝)

Problem Description There are n Doge Planets in the Doge Space. The conqueror of Doge Space is Super Doge, who is going to inspect his Doge Army on all Doge Planets. The inspection starts from Doge Planet 1 where DOS (Doge Olympic Statue) was built.

hdu 5113 Black And White (dfs回溯+剪枝)

Black And White Time Limit: 2000/2000 MS (Java/Others)    Memory Limit: 512000/512000 K (Java/Others) Total Submission(s): 854    Accepted Submission(s): 218 Special Judge Problem Description In mathematics, the four color theorem, or the four color

UVA-140 Bandwidth (回溯+剪枝)

题目大意:求一个使带宽最小的排列和最小带宽.带宽是指一个字母到其相邻字母的距离最大值. 题目分析:在递归生成全排列的过程中剪枝,剪枝方案还是两个.一.当前解不如最优解优时,减去:二.预测的理想解不必最优解优时,减去.将与当前最后一个位置上的字母相邻的字母全部接过来,便得理想解. 代码如下: # include<iostream> # include<cstdio> # include<string> # include<vector> # include&l