P1379 八数码难题

学了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;
}

猜你喜欢

转载自www.cnblogs.com/Garen-Wang/p/9350714.html