• hdu-1430 魔板 康拓展开+映射优化


    给定三种操作,将排列A转化为排列B,求最少步骤。

    这种题目可以只跑一次bfs,比如只跑"12345678",那么如果遇到"23456781"->某个字符串呢?因为每一个数字都是等价的,我们可以把2映射为1,3映射成2,以此类推。这样就可以用"12345678"跑出来的操作序列了。

    #include <iostream>
    #include <iomanip>
    #include <set>
    #include <cmath>
    #include <string>
    #include <algorithm>
    #include <queue>
    #include <vector>
    #include <map>
    #define LL long long
    using namespace std;
    class cantor
    {
    public:
    #define siz 8
        char c[siz]= {'1','2','3','4','5','6','7','8'};
        LL w[siz];
        bool vis[siz];
        cantor()
        {
            w[0]=1;
            for(int i=1; i<siz; i++)
                w[i]=w[i-1]*i;
        }
        void init()
        {
            for(int i=0; i<siz; i++)
                vis[i]=false;
        }
        LL makeCanto(string s)
        {
            init();
            LL rec=0;
            for(int i=0; i<siz; i++)
            {
                int d=0;
                for(int j=0; j<siz; j++)
                {
                    if(vis[j])
                        continue;
                    if(c[j]!=s[i])d++;
                    else
                    {
                        vis[j]=true;
                        break;
                    }
                }
                rec+=w[siz-i-1]*d;
            }
            return rec;
        }
        string recover(LL val)
        {
            init();
            string s="";
            for(int i=siz-1; i>=0; i--)
            {
                LL te=val/w[i];
                val%=w[i];
                for(int j=0,cnt=-1; j<siz; j++)
                {
                    if(vis[j])continue;
                    else cnt++;
                    if(cnt==te&&!vis[j])
                    {
                        s+=c[j];
                        vis[j]=true;
                        break;
                    }
                }
            }
            return s;
        }
    } fix;
    struct ax
    {
        int _1,_2;
        ax(int __1,int __2)
        {
            _1=__1;
            _2=__2;
        }
        friend bool operator < (ax a,ax b)
        {
            if(a._1==b._1)
                return a._2<b._2;
            return a._1<b._2;
        }
    };
    LL n,m;
    bool vis[50000];
    bool f;
    struct node
    {
        LL v;
        string a;
        node(LL V,string A)
        {
            v=V;
            a=A;
        }
    };
    map<int,string> ans;
    void bfs(int fr)
    {
        queue<node> q;
        node ini=node(fr,"");
        q.push(ini);
        fill(vis,vis+50000,false);
        vis[fr]=true;
        while(!q.empty())
        {
            node now=q.front();
            q.pop();
            ans[now.v]=now.a;
            string nows=fix.recover(now.v);
            string nx;
            //A
            nx=nows;
            for(int i=0; i<4; i++)
                swap(nx[i],nx[i+4]);
            if(!vis[fix.makeCanto(nx)])
                vis[fix.makeCanto(nx)]=true,q.push(node(fix.makeCanto(nx),now.a+"A"));
            //B
            for(int i=0; i<4; i++)
                nx[(i+1)%4]=nows[i],nx[4+(i+1)%4]=nows[4+i];
            if(!vis[fix.makeCanto(nx)])
                vis[fix.makeCanto(nx)]=true,q.push(node(fix.makeCanto(nx),now.a+"B"));
            //C
            nx=nows;
            nx[1]=nows[5];nx[2]=nows[1];
            nx[6]=nows[2];nx[5]=nows[6];
            if(!vis[fix.makeCanto(nx)])
                vis[fix.makeCanto(nx)]=true,q.push(node(fix.makeCanto(nx),now.a+"C"));
        }
    }
    int main()
    {
        cin.sync_with_stdio(false);
    
        string s1,s2;
        /*
        string nows,nx;
        cin>>nows;
    
        nx=nows;
        nx[1]=nows[5];nx[2]=nows[1];
        nx[6]=nows[2];nx[5]=nows[6];
        nows=nx;
        nx[1]=nows[5];nx[2]=nows[1];
        nx[6]=nows[2];nx[5]=nows[6];
        cout<<nx<<endl;
        */
        string fuck="12348765";
        bfs(fix.makeCanto(fuck));
        while(cin>>s1>>s2)
        {
            reverse(s1.begin()+4,s1.end());
            reverse(s2.begin()+4,s2.end());
            for(int i=0;i<8;i++)
            {
                int d;
                for(int j=0;j<8;j++)
                    if(s2[i]==s1[j])
                        d=j;
                s2[i]=fuck[d];
            }
            cout<<ans[fix.makeCanto(s2)]<<endl;
    
        }
    }
  • 相关阅读:
    MVC应用程序使用Entity Framework
    @Styles的nameSpace是什么
    创建第一个MVC应用程序
    计算DataTable某列的值(SUM)
    DropDownList 控件的SelectedIndexChanged事件触发不了
    在类中使用Response.Redirect()方法
    控制某个panel的display样式
    获取指定日期下个月份的第一天
    字符串如何还原为中文
    判断字符串中包含3个连续(升、降)或相同的数字
  • 原文地址:https://www.cnblogs.com/LukeStepByStep/p/8433598.html
Copyright © 2020-2023  润新知