学了Cantor展开,顺便切掉八数码“难题”。。。
没什么好说的,我一遍过的。
为什么没有什么好说的呢?因为我做过。
曾经太菜不会Cantor,只会用map暴力存,结果用了8000+ms。
我觉得比魔板容易。
代码:
#include<cstdio>
#include<algorithm>
const int maxn = 370000;
const int t[] = {0, 1, 2, 3, 8, 0, 4, 7, 6, 5};
const int frac[] = {1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880};
struct Nodes
{
int a[10];
int dist;
bool vis;
} s[maxn];
int start[10], start_cantor;
int end[10], end_cantor;
int queue[maxn], front, rear;
int cantor(int* x)
{
int ans = 1;
for(int i = 1; i <= 9; i++)
{
int s = 0;
for(int j = i + 1; j <= 9; j++)
{
if(x[i] > x[j]) s++;
}
ans += s * frac[9 - i];
}
return ans;
}
Nodes A(Nodes x)
{
Nodes ans;
int pos;
for(int i = 1; i <= 9; i++)
{
ans.a[i] = x.a[i];
if(x.a[i] == 0) pos = i;
}
if(pos >= 4) std::swap(ans.a[pos], ans.a[pos - 3]);
else ans.a[1] = 250;
return ans;
}
Nodes B(Nodes x)
{
Nodes ans;
int pos;
for(int i = 1; i <= 9; i++)
{
ans.a[i] = x.a[i];
if(x.a[i] == 0) pos = i;
}
if(pos <= 6) std::swap(ans.a[pos], ans.a[pos + 3]);
else ans.a[1] = 250;
return ans;
}
Nodes C(Nodes x)
{
Nodes ans;
int pos;
for(int i = 1; i <= 9; i++)
{
ans.a[i] = x.a[i];
if(x.a[i] == 0) pos = i;
}
if(pos % 3 != 1) std::swap(ans.a[pos], ans.a[pos - 1]);
else ans.a[1] = 250;
return ans;
}
Nodes D(Nodes x)
{
Nodes ans;
int pos;
for(int i = 1; i <= 9; i++)
{
ans.a[i] = x.a[i];
if(x.a[i] == 0) pos = i;
}
if(pos % 3 != 0) std::swap(ans.a[pos], ans.a[pos + 1]);
else ans.a[1] = 250;
return ans;
}
int bfs()
{
for(int i = 1; i <= 9; i++) s[start_cantor].a[i] = start[i];
s[start_cantor].dist = 0;
queue[rear++] = start_cantor; s[start_cantor].vis = true;
while(front < rear)
{
int x = queue[front++];
if(x == end_cantor) return s[x].dist;
for(int i = 1; i <= 4; i++)
{
Nodes temp;
if(i == 1) temp = A(s[x]);
else if(i == 2) temp = B(s[x]);
else if(i == 3) temp = C(s[x]);
else if(i == 4) temp = D(s[x]);
if(temp.a[1] == 250) continue;
int temp_cantor = cantor(temp.a);
if(!s[temp_cantor].vis)
{
s[temp_cantor] = temp;
s[temp_cantor].dist = s[x].dist + 1;
queue[rear++] = temp_cantor; s[temp_cantor].vis = true;
}
}
}
}
int main()
{
int temp; scanf("%d", &temp);
for(int i = 9; i >= 1; i--)
{
start[i] = temp % 10;
temp /= 10;
end[i] = t[i];
}
start_cantor = cantor(start);
end_cantor = cantor(end);
printf("%d\n", bfs());
return 0;
}