zoukankan      html  css  js  c++  java
  • 八数码问题

    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
  • 相关阅读:
    超过经理收入的员工
    搜索插入位置
    整数反转
    俩数之和
    tar 命令参数解释
    【记录】Transaction rolled back because it has been marked as rollback-only
    【转载】BIO、NIO、AIO
    【转载】JDK自带的log工具
    【转载】java8中的Calendar日期对象(LocalDateTime)
    【对象属性复制】BeanUtils.copyProperties(obj1, obj2);
  • 原文地址:https://www.cnblogs.com/mzh2017/p/8110703.html
Copyright © 2011-2022 走看看