zoukankan      html  css  js  c++  java
  • 洛谷

    https://www.luogu.org/problemnew/show/P2578

    一个挺搞的东西,用康托展开做记忆化搜索可以少一个log的查询。

    #include <bits/stdc++.h>
    using namespace std;
    #define ll long long
    
    static const int fac[] = {1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880,3628800};   // 阶乘
    
    //康托展开
    int cantor(int *a,int n)
    {
        int code=0;
        for(int i=0; i<n; i++)
        {
            int x=0;
            int c=1,m=1;//c记录后面的阶乘
            for(int j=i+1; j<n; j++)
            {
                if(a[j]<a[i])x++;
                m*=c;
                c++;
            }
            code+=x*m;
        }
        //printf("cantor=%d
    ",code);
        return code;
    }
    
    //逆康托展开
    void decantor(int code,int *a,int n)
    {
        bool vis[11]= {};
        for(int i=0; i<n; i++)
        {
            int r = code / fac[n-i-1];
            code %= fac[n-i-1];
            int cnt = 0;
            int j;
            for(j=1; j<=n; j++)
            {
                if(vis[j]==0)
                {
                    cnt++;
                    if(cnt==r+1)
                    {
                        a[i]=j;
                        vis[j]=1;
                        break;
                    }
                }
            }
        }
    
        /*printf("decantor=");
        for(int i=0; i<n; i++)
        {
            printf(" %d",a[i]);
        }
        printf("
    ");*/
    }
    
    ll rot1(ll code)
    {
        int a[9];
        decantor(code,a,9);
        int t=a[0];
        a[0]=a[3];
        a[3]=a[6];
        a[6]=a[7];
        a[7]=a[8];
        a[8]=a[5];
        a[5]=a[2];
        a[2]=a[1];
        a[1]=t;
        int ans=cantor(a,9);
        return ans;
    }
    
    int rot2(int code)
    {
        int a[9];
        decantor(code,a,9);
        int t=a[5];
        a[5]=a[4];
        a[4]=a[3];
        a[3]=t;
        int ans=cantor(a,9);
        return ans;
    }
    
    struct dat
    {
        int cur;
        int pre;
    } d,dt,data[362880];
    
    queue<dat> q;
    
    void print(int code)
    {
        int a[9],n=9;
    
        bool vis[11]= {};
        for(int i=0; i<n; i++)
        {
            int r = code / fac[n-i-1];
            code %= fac[n-i-1];
            int cnt = 0;
            int j;
            for(j=1; j<=n; j++)
            {
                if(vis[j]==0)
                {
                    cnt++;
                    if(cnt==r+1)
                    {
                        a[i]=j;
                        vis[j]=1;
                        break;
                    }
                }
            }
        }
    
        printf("
    ");
        for(int i=0; i<n; i++)
        {
            printf("%d%c",a[i]-1," 
    "[i%3==2]);
        }
    }
    
    void show(dat d)
    {
        stack<ll> s;
        s.push(d.cur);
        while(d.pre!=-1)
        {
            s.push(d.pre);
            d=data[d.pre];
        }
    
        printf("%d",s.size()-1);
    
        while(!s.empty())
        {
            print(s.top());
            s.pop();
        }
    }
    
    inline bool found(int code){
        return !code;
    }
    
    void bfs(int s)
    {
        //memset(data,0,sizeof(data));
    
        d.cur=s;
        d.pre=-1;
    
        if(found(d.cur))
        {
            show(d);
            return;
        }
    
        data[d.cur]=d;
        q.push(d);
    
        while(!q.empty())
        {
            d=q.front();
            q.pop();
    
            int t1=rot1(d.cur);
            if(data[t1].cur)
                ;
            else
            {
                dt.cur=t1;
                dt.pre=d.cur;
                if(found(dt.cur))
                {
                    show(dt);
                    return;
                }
                data[t1]=dt;
                q.push(dt);
            }
    
            int t2=rot2(d.cur);
            if(data[t2].cur)
                ;
            else
            {
                dt.cur=t2;
                dt.pre=d.cur;
                if(found(dt.cur))
                {
                    show(dt);
                    return;
                }
                data[t2]=dt;
                q.push(dt);
            }
        }
    
        printf("UNSOLVABLE
    ");
    }
    
    int main()
    {
        int a[9];
        for(int i=0; i<9; i++)
        {
            scanf("%d",&a[i]);
            a[i]++;
        }
    
        int s=cantor(a,9);
        bfs(s);
    }
  • 相关阅读:
    新的页面事件的添加
    excel里数字0不显示
    VB6接口、对象比较等
    SQL SERVER服务停止和启动命令行
    如何更改VS2008的字体和大小
    如何部署windows service
    模式应用 - 利用工厂模式制作自己的"小程序测试工厂"
    解决Oracle Temp01.dbf不断变大的问题
    如何配置VS2008让它用外置IIS进行调试
    使用JQuery Autocomplete插件(一)
  • 原文地址:https://www.cnblogs.com/Yinku/p/10541932.html
Copyright © 2011-2022 走看看