zoukankan      html  css  js  c++  java
  • hdu 1430(BFS+康托展开+映射+输出路径)

    魔板

    Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
    Total Submission(s): 2874    Accepted Submission(s): 635


    Problem Description
    在 魔方风靡全球之后不久,Rubik先生发明了它的简化版——魔板。魔板由8个同样大小的方块组成,每个方块颜色均不相同,可用数字1-8分别表示。任一时 刻魔板的状态可用方块的颜色序列表示:从魔板的左上角开始,按顺时针方向依次写下各方块的颜色代号,所得到的数字序列即可表示此时魔板的状态。例如,序列 (1,2,3,4,5,6,7,8)表示魔板状态为:

    1 2 3 4
    8 7 6 5

    对于魔板,可施加三种不同的操作,具体操作方法如下:

    A: 上下两行互换,如上图可变换为状态87654321
    B: 每行同时循环右移一格,如上图可变换为41236785
    C: 中间4个方块顺时针旋转一格,如上图可变换为17245368

    给你魔板的初始状态与目标状态,请给出由初态到目态变换数最少的变换步骤,若有多种变换方案则取字典序最小的那种。
     
    Input
    每组测试数据包括两行,分别代表魔板的初态与目态。
     
    Output
    对每组测试数据输出满足题意的变换步骤。
     
    Sample Input
    12345678 17245368 12345678 82754631
     
    Sample Output
    C AC
     
    Author
    LL
     
    Source
     
     
    题解:康托展开没什么玄乎的,就相当于HASH的功能,主要是映射很牛,解法,映射:
    这里已经解释的很清楚了,我就直接引用了.

    列如:位置:12345678                12345678

               起初: 63728145       变      12345678

               终点: 86372541       成       51234876

    解释一下:初:6在第1个位,那么在终点中找6用1代替,3在第2个位,在终点中找3用2代替,依次类推。

    一开始我们就先按 12345678 这样的顺序建立了一棵像树一样的,如果直接从初态不进行转变的话,那么我们的结果可能有很多的走法,有可能是先走A或B都可以到目标,有多条路时,但是先走了B的路径,必须要输出小的也就是从A开始的那条路,那怎么办呢,就可以用转化的思想了,把初始状态变成12345678,这样的话,我们一开始就是从这样的顺序算出来的!!所以必须先进行转换,在从目标往上找并记下路径,一直找到最终父节点:12345678.

    这题映射之后直接一次BFS就行了...非常NB。。

    ///X=a[n]*(n-1)!+a[n-1]*(n-2)!+...+a[i]*(i-1)!+...+a[1]*0! a[i]表示第i个元素的逆序数
    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <cmath>
    #include <queue>
    #include <string>
    #include <map>
    using namespace std;
    const int N = 50000;
    int a[10],b[10];
    char str[50],str1[50];
    bool vis[N];
    int fab[10]={1,1,2,6,24,120,720,5040};
    struct Node
    {
        int val[10];
        int Hash;
    };
    struct Way{
        char way; ///记录路径
        int pre;
    }node2[N];
    int contor(Node s){
        int x= 0 ;
        for(int i=8;i>=1;i--){
            int cnt = 0;
            for(int j=i-1;j>=1;j--){
                if(s.val[i]<s.val[j]) cnt++;
            }
            x+=cnt*fab[i-1];
        }
        return x;
    }
    void A(Node &s){
        swap(s.val[1],s.val[8]);
        swap(s.val[2],s.val[7]);
        swap(s.val[3],s.val[6]);
        swap(s.val[4],s.val[5]);
    }
    void B(Node &s){
        swap(s.val[1],s.val[2]),swap(s.val[1],s.val[3]),swap(s.val[1],s.val[4]);
        swap(s.val[5],s.val[6]),swap(s.val[6],s.val[7]),swap(s.val[7],s.val[8]);
    }
    void C(Node &s){
        swap(s.val[2],s.val[3]),swap(s.val[2],s.val[6]),swap(s.val[2],s.val[7]);
    }
    void bfs(Node s)
    {
        for(int i=0;i<N;i++){
            node2[i].pre = -1;
        }
        memset(vis,false,sizeof(vis));
        queue<Node> q;
        node2[s.Hash].pre = -1;
        vis[s.Hash] = true;
        q.push(s);
        while(!q.empty()){
            Node now = q.front();
            q.pop();
            Node next;
            next = now;
            A(next);
            int k = contor(next);
            if(!vis[k]){
                vis[k] = true;
                next.Hash = k;
                node2[next.Hash].pre = now.Hash;
                node2[next.Hash].way = 'A';
                q.push(next);
            }
            next = now;
            B(next);
            k = contor(next);
            if(!vis[k]){
                vis[k] = true;
                next.Hash = k;
                node2[next.Hash].pre = now.Hash;
                node2[next.Hash].way = 'B';
                q.push(next);
            }
            next = now;
            C(next);
            k = contor(next);
            if(!vis[k]){
                vis[k] = true;
                next.Hash = k;
                node2[next.Hash].pre = now.Hash;
                node2[next.Hash].way = 'C';
                q.push(next);
            }
        }
    }
    struct Node3{
        char c;
        int idx;
    }node3[50];
    void dfs(int x){
        if(node2[x].pre==-1) return;
        dfs(node2[x].pre);
        printf("%c",node2[x].way);
    }
    int main()
    {
        Node s;
        for(int i=1;i<=8;i++){
            s.val[i] = i;
        }
        s.Hash = contor(s);
        bfs(s);
        while(scanf("%s",str+1)!=EOF)
        {
            scanf("%s",str1+1);
            for(int i=1;i<=8;i++){
                node3[i].c = str[i];
                node3[i].idx = i;
            }
            Node s;
            for(int i=1;i<=8;i++){
                for(int j=1;j<=8;j++){
                    if(str1[i]==node3[j].c){
                        s.val[i] = node3[j].idx;
                        break;
                    }
                }
            }
            int x= contor(s);
            dfs(x);
            printf("
    ");
        }
    }
  • 相关阅读:
    关于 Node.js: 所有PHP开发人员应该知道的5点
    HTML5网站大观:分享8个精美的 HTML5 网站案例
    一些新的 UI 图免费下载
    用HTML5/CSS3/JS开发Android/IOS应用
    Why C++ ? 王者归来
    响应式网页设计
    60款很酷的 jQuery 幻灯片演示和下载
    25 JavaScript的幻灯片用于在Web布局的精彩案例
    10个帮助你优化网站的 .htaccess 技巧
    视差滚动在网页设计中应用的21个优秀案例
  • 原文地址:https://www.cnblogs.com/liyinggang/p/5746543.html
Copyright © 2011-2022 走看看