这篇文章写得比较详细
对于搜索的优化:
1 从大往小搜
2 从原字符串的最低位开始搜,并且从上往下,这个可以记录在pos数组里
最后就是一些判断的函数了,文章写得挺详细的,看了他的才会写
#includeusing namespace std;string a, b, c;bool vis[30];int pos[30], res[30], tot,n;void parse(){ for (int i = n - 1; i >= 0; i--)//从右往左 顺序不能更改变,否则超时 { int a1 = a[i] - 'A', b1 = b[i] - 'A', c1 = c[i] - 'A';//从上到下 if (!vis[a1]) { vis[a1] = true; pos[tot++] = a1; } if (!vis[b1]) { vis[b1] = true; pos[tot++] = b1; } if (!vis[c1]) { vis[c1] = true; pos[tot++] = c1; } }}bool valid()//最终检查{ int jinwei=0,sum=0; for (int i = n - 1; i >= 0; i--) { int a1 = a[i] - 'A', b1 = b[i] - 'A', c1 = c[i] - 'A'; sum = (res[a1] + res[b1]+jinwei) % n; jinwei = (res[a1] + res[b1] + jinwei) / n; if (sum != res[c1]) return false; } if (jinwei != 0) return false; return true;}bool check()//粗略检查{ for (int i = n - 1; i >= 0; i--)//顺序可以改为0~n-1,时间会略有延长 { // 对于一竖排上的3个数 a b c int a1 = a[i] - 'A', b1 = b[i] - 'A', c1 = c[i] - 'A'; if (res[a1] != -1 && res[b1] != -1 && res[c1] != -1) { if ((res[a1] + res[b1]) % n != res[c1] && (res[a1] + res[b1] + 1) % n != res[c1]) return false; } else if (res[a1] != -1 && res[b1] != -1 && res[c1] == -1) { if (vis[(res[a1] + res[b1]) % n] && vis[(res[a1] + res[b1] + 1) % n]) return false; } else if (res[a1] != -1 && res[c1] != -1 && res[b1] == -1 ) //知道a c { if (vis[(res[c1] - res[a1] + n) % n] && vis[(res[c1] - res[a1] - 1 + n) % n]) return false; } else if (res[a1] == -1 && res[b1] != -1 && res[c1] != -1) { if (vis[(res[c1] - res[b1] + n) % n] && vis[(res[c1] - res[b1] - 1 + n) % n]) return false; } } return true;}void dfs(int k){ if (!check()) return; if (k == n) { if (valid()) { for (int i = 0; i < n; i++) cout << res[i] << " \n"[i == n - 1]; exit(0);//直接退出 } return; } for (int i = n-1; i >=0 ; i--)//很重要,顺序不可以改变,否则超时 { if (!vis[i]){ vis[i] = true; res[pos[k]] = i; dfs(k + 1); res[pos[k]] = -1; vis[i] = false; } }}int main(){ cin >> n; cin>>a >> b >> c; parse();//处理pos数组,优化搜索 memset(res, -1, sizeof(res)); memset(vis, false, sizeof(vis));//这里一定要重新清0 dfs(0); return 0;}