我在本题使用很多 STL 后会 TLE 一个点,但是程序思路正确。代码如下:
#include <iostream>
#include <queue>
#include <set>
using namespace std;
int dx[][8] = {
{7, 6, 5, 4, 3, 2, 1, 0},
{3, 0, 1, 2, 5, 6, 7, 4},
{0, 6, 1, 3, 4, 2, 5, 7}
};
string s, now(8, 0);
struct node {
string s, t;
} p;
queue<node> q;
set<string> S;
int main() {
for(int i = 0; i < 8; i++) s.push_back(cin.get()), cin.get();
q.push({"12345678", string()});
while(true) {
p = q.front();
if(p.s == s) {
cout << p.t.length();
for(int i = 0; i < p.t.length(); i++) {
if(!(i % 60)) cout.put('\n');
cout.put(p.t[i]);
}
break;
}
q.pop();
S.insert(p.s);
for(int i = 0; i < 3; i++) {
for(int j = 0; j < 8; j++)
now[j] = p.s[dx[i][j]];
if(!S.count(now)) q.push({now, p.t+char('A'+i)});
}
}
return 0;
}
为了通过最后一个点,我开始进行常数优化。使用 C 字符串、手写队列、康托展开。优化后的代码如下:
#include <cstdio>
#include <cstring>
const int dx[][8] = {
{7, 6, 5, 4, 3, 2, 1, 0},
{3, 0, 1, 2, 5, 6, 7, 4},
{0, 6, 1, 3, 4, 2, 5, 7}
}, fac[] = {1, 1, 2, 6, 24, 120, 720, 5040};
char s[10], now[10], q1[50000][10], q2[50000][51];
bool f[40320];
int l, r = 1, len;
int cantor(char *__s) {
int r = 0;
for(int i = 0, t; i < 8; i++) {
t = 0;
for(int j = i + 1; j < 8; j++)
if(__s[i] > __s[j]) t++;
r += t * fac[i];
}
return r;
}
int main() {
for(int i = 0; i < 8; i++) s[i] = getchar(), getchar();
strcpy(*q1, "12345678");
while(l < r) {
if(!strcmp(q1[l], s)) {
printf("%d", len = strlen(q2[l]));
for(int i = 0; i < len; i++) {
if(!(i % 60)) putchar('\n');
putchar(q2[l][i]);
}
break;
}
f[cantor(q1[l])] = true;
for(int i = 0; i < 3; i++) {
for(int j = 0; j < 8; j++)
now[j] = q1[l][dx[i][j]];
if(!f[cantor(now)])
strcpy(q1[r], now),
strcpy(q2[r], q2[l]),
q2[r][strlen(q2[r])] = 'A' + i,
r++;
}
l++;
}
return 0;
}
但是,优化后的代码只能通过一半数据,其余会 WA(没输出)。具体地,队列空了之后仍未找到解。
这是为什么?我该如何修改?
关于悬赏:可以直接给我调好的代码并指出错误之处,也可在讨论区与我讨论。第一个帮我修复错误的将获得人民币 5 元。