• HDU1430;魔板(BFS+康托展开)


    传送门

    题意

    给出初始序列与终止序列,给出三种操作,问最少经过几次操作能使初始->终止,输出操作(字典序最小)

    分析

    字符串只有8个字符,使用康托展开。
    1.BFS将所有序列从"12345678"操作得到,能够保证字典序与次数最小(采用string)
    2.接下来将初始序列变成"12345678",相应终止序列也变化,该操作由下列代码实现

    R(i,0,8) pos[s1[i]-'0']=i+1;
    R(i,0,8) s2[i]=pos[s2[i]-'0'];
    

    代码

    #include<bits/stdc++.h>
    using namespace std;
    
    #define ll long long
    #define F(i,a,b) for(int i=a;i<=b;++i)
    #define R(i,a,b) for(int i=a;i<b;++i)
    #define mem(a,b) memset(a,b,sizeof(a))
    #define cpy(a,b) memcpy(a,b,sizeof(b))
    string s1,s2,ans[100100];
    int a[10]={1,1,2,6,24,120,720,5040},pos[10];
    bool vis[100100];
    int cal(string &s)//cnt=a[i]*(n-i-1)!
    {
        int ret=0;
        R(i,0,7)
        {
            int tmp=0;
            R(j,i+1,8) if(s[i]>s[j]) tmp++;
            ret+=tmp*a[7-i];
        }
        //printf("ret=%d
    ",ret);
        return ret;
    }
    struct node
    {
        string s;
        int value;
    };
    
    void op1(string &s)
    {
        F(i,1,4) swap(s[i-1],s[8-i]);
    }
    void op2(string &s)
    {
        for(int i=3;i;--i) swap(s[i],s[i-1]);
        for(int i=4;i<7;++i) swap(s[i],s[i+1]);
    }
    void op3(string &s)
    {
        swap(s[1],s[6]);swap(s[6],s[5]);swap(s[2],s[5]);
    }
    queue<node>q;
    void bfs()
    {
        string s="12345678";
        node p;
        p.s=s;
        p.value=cal(s);
        vis[p.value]=1;
        ans[p.value]="";
        q.push(p);
        while(!q.empty())
        {
            //puts("1");
            p=q.front();q.pop();
            //if(vis[p.value]) continue;
            F(i,1,3)
            {
                if(i==1)
                {
                    node pp=p;
                    op1(pp.s);
                    pp.value=cal(pp.s);
                    if(!vis[pp.value])
                    {
                        vis[pp.value]=1;ans[pp.value]=ans[p.value]+'A';
                        q.push(pp);
                    }
                }
                if(i==2)
                {
                    node pp=p;
                    op2(pp.s);
                    pp.value=cal(pp.s);
                    if(!vis[pp.value])
                    {
                        vis[pp.value]=1;ans[pp.value]=ans[p.value]+'B';
                        q.push(pp);
                    }
    
                }
                if(i==3)
                {
                    node pp=p;
                    op3(pp.s);
                    pp.value=cal(pp.s);
                    if(!vis[pp.value])
                    {
                        vis[pp.value]=1;ans[pp.value]=ans[p.value]+'C';
                        q.push(pp);
                    }
                }
            }
        }
    }
    
    int main()
    {
        bfs();
        while(cin>>s1>>s2)
        {
            R(i,0,8) pos[s1[i]-'0']=i+1;
            R(i,0,8) s2[i]=pos[s2[i]-'0'];
            cout<<ans[cal(s2)]<<endl;
        }
        return 0;
    }
    
    
  • 相关阅读:
    基于MFC的Media Player播放器的制作(1---播放器界面的布局)
    Codeforces 1182
    Codeforces 1169
    Codeforces 1167
    Codeforces 1166
    Codeforces 1148
    *Codeforces 1162
    Codeforces 1159
    点分治
    高斯消元*
  • 原文地址:https://www.cnblogs.com/chendl111/p/6569259.html
Copyright © 2020-2023  润新知