您的位置:首页 > 其它

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

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

由于数据量很大,本来想用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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: