题意:给出一些数字和一个目标数字,要求你在数字间添加+-*/,让表达式能达到目标数字,运算符号的优先级都是一样的。
由于数据量很大,本来想用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 ", 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 "); } return 0; }