修改的地方不多,如何让代码速度更快呢?对于搜索而言,我们可以尽量的减少解答树的层数,之前我在判断dfs是否有唯一解时搜索的
深度为8后来经过优化后深度为4,这样快了许多。
// UVa 12107 // IDA* + 剪枝 #include <cstdio> #include <cstring> #include <string> #include <set> using namespace std; const char alpha[] = { '*', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' }; int c1, c2, c3, cnt, maxd; char str[20], ans[20]; set<string> Set; bool Vis() { if (str[0] == '0' || str[c1] == '0' || str[c2] == '0') return false; if (str[c1-1] != '*' && str[c2-1] != '*' && str[c3-1] != '*') { int a = str[c1-1] - '0', b = str[c2-1] - '0', c = str[c3-1] - '0'; return (a*b) % 10 == c; } return true; } bool Vis1() { int a = 0, b = 0, c = 0; for (int i = 0; i < c1; ++i) a = a * 10 + str[i] - '0'; for (int i = c1; i < c2; ++i) b = b * 10 + str[i] - '0'; c = a * b; for (int i = c3-1; i >= c2; --i) { if (!c) return false; int d = c % 10; c /= 10; if (str[i] != '*' && str[i] - '0' != d) return false; } if (c) return false; return true; } void dfs1(int from) { int i; for (i = from; i < strlen(str); ++i) if (str[i] == '*') break; if (i >= c2) { if (Vis1()) ++cnt; return; } for (int j = 1; j < 11; ++j) { char temp = str[i]; str[i] = alpha[j]; if (Vis()) dfs1(i+1); str[i] = temp; if (cnt > 1) return; } } bool better() { for (int i = 0; i < c3; ++i) if (str[i] != ans[i]) { return ans[i] == ' ' || str[i] < ans[i]; } return false; } bool dfs(int d, int from) { if (d == maxd) { cnt = 0; memcpy(ans, str, sizeof(ans)); if (Vis()) dfs1(0); return cnt == 1; } if (from == c3) return false; for (int j = 0; j < 11; ++j) { char temp = str[from]; if (str[from] == alpha[j]) if (dfs(d, from+1)) return true; if (str[from] != alpha[j]) { str[from] = alpha[j]; if (dfs(d+1, from+1)) return true; } str[from] = temp; } return false; } int main() { int kase = 0; char a[10], b[10], c[10]; while (scanf("%s", a) == 1 && a[0] != '0') { scanf("%s%s", b, c); c1 = strlen(a), c2 = strlen(a) + strlen(b), c3 = strlen(a) + strlen(b) + strlen(c); memcpy(str, a, sizeof(a)); strcat(str, b), strcat(str, c); for (int i = 0; i < c3; ++i) ans[i] = ' '; char rem[20]; memcpy(rem, str, sizeof(rem)); for (maxd = 0; ; ++maxd) { Set.clear(); if (dfs(0, 0)) break; memcpy(str, rem, sizeof(str)); } printf("Case %d: ", ++kase); for (int i = 0; i < c1; ++i) printf("%c", ans[i]); printf(" "); for (int i = c1; i < c2; ++i) printf("%c", ans[i]); printf(" "); for (int i = c2; i < c3; ++i) printf("%c", ans[i]); printf(" "); } return 0; }