八数码问题

1.本题是一个基本的BFS模板,主要内容在于如何状态判重,我这里采用的是康托展开。

2.至于暴搜的状态我这里才、采用的是一个8位数,然后用数位分割转换状态。

康托展开:

long long bas[10]={1,1,2,6,24,120,720,5040,40320,362880}//阶乘
int Cantor_expansion(long long x)
{
    long long wei[10];
    for(int i=1;i<=9;i++)
    wei[i]=x/a[9-i]%10;
    int ans=0;
    for(int i=1;i<=9;i++)
    {
        int tmp=0;
        for(int j=i+1;j<=9;j++)
        if(wei[j]<wei[i])
        tmp++;
        ans+=tmp*bas[9-i];
    }
    return ans;
} 

四个操作:

void up()
{
    int xx=q.front().p;
    if(xx-3<1)
    return;
    long long x=q.front().n;
    int wei=x/a[9-(xx-3)]%10;
    x=x-wei*a[9-(xx-3)]+wei*a[9-xx];
    int tmp=Cantor_expansion(x);
    if(!visit[tmp])
    {
        visit[tmp]=1;
        tonod c;
        c.p=xx-3;
        c.n=x;
        c.step=q.front().step+1;
        q.push(c);
        if(x==m)
        {
            step=c.step;
            bo=1;
        }
    }
}
void down()
{
    int xx=q.front().p;
    if(xx+3>9)
    return;
    long long x=q.front().n;
    int wei=x/a[9-(xx+3)]%10;
    x=x-wei*a[9-(xx+3)]+wei*a[9-xx];
    int tmp=Cantor_expansion(x);
    if(!visit[tmp])
    {
        visit[tmp]=1;
        tonod c;
        c.p=xx+3;
        c.n=x;
        c.step=q.front().step+1;
        q.push(c);
        if(x==m)
        {
            step=c.step;
            bo=1;
        }
    }
}
void left()
{
    int xx=q.front().p;
    if(xx==1||xx==4||xx==7)
    return;
    long long x=q.front().n;
    int wei=x/a[9-(xx-1)]%10;
    x=x-wei*a[9-(xx-1)]+wei*a[9-xx];
    int tmp=Cantor_expansion(x);
    if(!visit[tmp])
    {
        visit[tmp]=1;
        tonod c;
        c.p=xx-1;
        c.n=x;
        c.step=q.front().step+1;
        q.push(c);
        if(x==m)
        {
            step=c.step;
            bo=1;
        }
    }
}
void right()
{
    int xx=q.front().p;
    if(xx==3||xx==6||xx==9)
    return;
    long long x=q.front().n;
    int wei=x/a[9-(xx+1)]%10;
    x=x-wei*a[9-(xx+1)]+wei*a[9-xx];
    int tmp=Cantor_expansion(x);
    if(!visit[tmp])
    {
        visit[tmp]=1;
        tonod c;
        c.p=xx+1;
        c.n=x;
        c.step=q.front().step+1;
        q.push(c);
        if(x==m)
        {
            step=c.step;
            bo=1;
        }
    }
}

标程:

#include<queue> 
#include<cstdio>
#include<cstring> 
#include<iostream>
using namespace std;
long long bas[10]={1,1,2,6,24,120,720,5040,40320,362880},a[9]={1,10,100,1000,10000,100000,1000000,10000000,100000000};
struct tonod{
    long long n;
    int p,step;
};
queue<tonod> q;
bool visit[10000000],bo=0;
long long m=123804765;
int step=0;
int Cantor_expansion(long long x)
{
    long long wei[10];
    for(int i=1;i<=9;i++)
    wei[i]=x/a[9-i]%10;
    int ans=0;
    for(int i=1;i<=9;i++)
    {
        int tmp=0;
        for(int j=i+1;j<=9;j++)
        if(wei[j]<wei[i])
        tmp++;
        ans+=tmp*bas[9-i];
    }
    return ans;
} 
void up()
{
    int xx=q.front().p;
    if(xx-3<1)
    return;
    long long x=q.front().n;
    int wei=x/a[9-(xx-3)]%10;
    x=x-wei*a[9-(xx-3)]+wei*a[9-xx];
    int tmp=Cantor_expansion(x);
    if(!visit[tmp])
    {
        visit[tmp]=1;
        tonod c;
        c.p=xx-3;
        c.n=x;
        c.step=q.front().step+1;
        q.push(c);
        if(x==m)
        {
            step=c.step;
            bo=1;
        }
    }
}
void down()
{
    int xx=q.front().p;
    if(xx+3>9)
    return;
    long long x=q.front().n;
    int wei=x/a[9-(xx+3)]%10;
    x=x-wei*a[9-(xx+3)]+wei*a[9-xx];
    int tmp=Cantor_expansion(x);
    if(!visit[tmp])
    {
        visit[tmp]=1;
        tonod c;
        c.p=xx+3;
        c.n=x;
        c.step=q.front().step+1;
        q.push(c);
        if(x==m)
        {
            step=c.step;
            bo=1;
        }
    }
}
void left()
{
    int xx=q.front().p;
    if(xx==1||xx==4||xx==7)
    return;
    long long x=q.front().n;
    int wei=x/a[9-(xx-1)]%10;
    x=x-wei*a[9-(xx-1)]+wei*a[9-xx];
    int tmp=Cantor_expansion(x);
    if(!visit[tmp])
    {
        visit[tmp]=1;
        tonod c;
        c.p=xx-1;
        c.n=x;
        c.step=q.front().step+1;
        q.push(c);
        if(x==m)
        {
            step=c.step;
            bo=1;
        }
    }
}
void right()
{
    int xx=q.front().p;
    if(xx==3||xx==6||xx==9)
    return;
    long long x=q.front().n;
    int wei=x/a[9-(xx+1)]%10;
    x=x-wei*a[9-(xx+1)]+wei*a[9-xx];
    int tmp=Cantor_expansion(x);
    if(!visit[tmp])
    {
        visit[tmp]=1;
        tonod c;
        c.p=xx+1;
        c.n=x;
        c.step=q.front().step+1;
        q.push(c);
        if(x==m)
        {
            step=c.step;
            bo=1;
        }
    }
}
int main()
{
    long long n;
    cin>>n;
    if(n==m)
    {
        printf("0");
        return 0;
    }
    int wei[10],xx=9;
    for(int i=1;i<=9;i++)
    {
        wei[i]=n/a[9-i]%10;
        if(wei[i]==0)
        {
            xx=i;
            break;
        }
    }
    tonod c;
    c.n=n;
    c.p=xx;
    c.step=0;
    q.push(c);
    visit[Cantor_expansion(n)];
    while(!q.empty())
    {
        up();
        down();
        left();
        right();
        if(bo)
        {
            printf("%d",step);
            return 0;
        }
        q.pop();
    }
}
View Code
原文地址:https://www.cnblogs.com/mzh2017/p/8110703.html