UVa 10400 - Game Show Math 游戏中的数学 dfs+判重

时间:2021-07-14 10:56:28

题意:给出一些数字和一个目标数字,要求你在数字间添加+-*/,让表达式能达到目标数字,运算符号的优先级都是一样的。

由于数据量很大,本来想用map<string>判重的,结果还是超时了,然后发现彻底的把题意理解错了,我以为数字的位置可以变,还用了全排列,结果人家没说能变换顺序。。。

修改后还是超时了 = =。。。

果然map是行不通的,太耗时了,由于答案在[-32000,32000]之间,而你到达某一个位置的运算结果如果是以前以及算过的,后面的计算就算是重复的了,可以利用这个判重。

数据不是很大,不需要压缩直接开数组。

代码:

 /*
* Author: illuz <iilluzen[at]gmail.com>
* Blog: http://blog.csdn.net/hcbbt
* File: uva10400.cpp
* Lauguage: C/C++
* Create Date: 2013-09-01 21:34:49
* Descripton: uva10400, dfs
*/
#include <cstdio>
#include <cstring>
#include <string>
using namespace std;
#define rep(i, n) for (int i = 0; i < (n); i++) const int MAXN = 101;
int a[MAXN], res, n;
bool flag, vis[MAXN][32000 * 2 + 1];
const string ept; bool ok(int a, int b) {
if (b >= -32000 && b <= 32000 && !vis[a][b + 32000]) {
vis[a][b + 32000] = true;
return true;
}
return false;
} void dfs(int d, int s, string t) {
if (flag) return;
if (d == n) {
if (s == res) {
flag = true;
rep(i, n - 1)
printf("%d%c", a[i], t[i]);
printf("%d=%d\n", a[n - 1], res);
}
return;
}
if (ok(d + 1, s + a[d + 1])) {
dfs(d + 1, s + a[d + 1], t + '+');
}
if (ok(d + 1, s - a[d + 1])) {
dfs(d + 1, s - a[d + 1], t + '-');
}
if (ok(d + 1, s * a[d + 1])) {
dfs(d + 1, s * a[d + 1], t + '*');
}
if (a[d + 1] && s % a[d + 1] == 0 && ok(d + 1, s / a[d + 1])) {
dfs(d + 1, s / a[d + 1], t + '/');
}
} int main() {
int t;
scanf("%d", &t);
while (t--) {
memset(vis, 0, sizeof(vis));
memset(a, 0, sizeof(a));
scanf("%d", &n);
rep(i, n) scanf("%d", &a[i]);
scanf("%d", &res);
flag = false;
dfs(0, a[0], ept);
if (flag == false) printf("NO EXPRESSION\n");
}
return 0;
}