zoukankan      html  css  js  c++  java
  • HDU1430 BFS + 打表 + 康托展开(转)

     题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1430 , 一道比较好的题。

      这道题要用到很多知识,康托展开、BFS、打表的预处理还要用到一一映射,做完受益匪浅。

      其实这道题也可以用双向BFS来写,思路也已经有了,过几天再来写。

      本文持续更新。


    先说搜索部分:

      对于魔板的每一个状态,都可以进行A、B、C三种操作,所以按照图论来讲,就是操作前的状态可以到达操作后的状态,所以就这样转换成了广搜问题。

      这里要注意一点,由于题目要求字典序最小的,所以搜索的时候要按照ABC的顺序来。

    再说康托展开:

      康托展开其实就是哈希的一种,即用一个数字来表示一个排列。比如说{A , B , C , D}的全排列中,ABCD对应的康托展开的值为0,ABDC对应的康托展开值为1...

      关于康托展开算法,具体见:http://www.cnblogs.com/mhpp/p/8039879.html

    关于打表预处理:

      由于魔板的所有状态都可以转换为“12345678”,所以这时就需要做一个映射:每组数据都有一个起始状态与目标状态,可以把起始状态用一种映射关系映射为“12345678”,然后用这种映射关系再去改一下终止状态。例如:初态为“12653487” , 目态为“12345678” ;这时映射后初态为“12345678”,即f[1] = 1 , f[2] = 2 , f[6] = 3 , f[5] = 4 , f[3] = 5 , f[4] = 6 , f[8] = 7 , f[7] = 8 ,按照这种映射关系目态应为“12564387”。代码应为:f[start[i] - '0'] = i ; end[i] = f[end[i] - '0'] + '0';

      有这样一个映射前提,就可以先用BFS预处理从“12345678”到其余所有状态的步骤,然后输入每组测试数据后进行转换,然后这时候就变成了求从“12345678”到映射后的目标状态的步骤的问题,这时按照存好的路径输出即可。

    BFS + 打表:

     1 #include <iostream>
     2 #include <queue>
     3 #include <string>
     4 #include <string.h>
     5 using namespace std;
     6 
     7 const int maxn = 50000 + 5;
     8 int vis[maxn];
     9 string ans[maxn];
    10 int fac[]={1 , 1 , 2 , 6 , 24 , 120 , 720 , 5040 , 40320};//1!,2!...8!
    11 int Cantor(string str)//康托展开
    12 {
    13     int ret = 0;
    14     int n = str.size();
    15     for(int i = 0 ; i < n ; i++) {
    16         int cnt = 0;
    17         for(int j = i ; j < n ; j++)//str[i]在子串中是第几大
    18             if(str[j] < str[i])
    19                 cnt++;
    20         ret += cnt * fac[n - i - 1];//累加
    21     }
    22     return ret;
    23 }
    24 void move_A(string &str)
    25 {
    26     for(int i = 0 ; i < 4 ; i++)
    27         swap(str[i] , str[7 - i]);
    28 }
    29 void move_B(string &str)
    30 {
    31     for(int i = 3 ; i > 0 ; i--)
    32         swap(str[i] , str[i - 1]);
    33     for(int i = 4 ; i < 7 ; i++)
    34         swap(str[i] , str[i + 1]);
    35 }
    36 void move_C(string &str)
    37 {
    38     char tmp = str[6];
    39     str[6] = str[5];
    40     str[5] = str[2];
    41     str[2] = str[1];
    42     str[1] = tmp;
    43 }
    44 void BFS(string str)//预处理,扩张由状态“12345678”,能到的所有状态
    45 {
    46     memset(vis , 0 , sizeof(vis));
    47     queue <string> que;
    48     que.push(str);
    49     int x = Cantor(str);
    50     vis[x] = 1;
    51     ans[x] = "";
    52     while(!que.empty()) {
    53         string u = que.front();
    54         que.pop();
    55         int i = Cantor(u);
    56         string tmp = u;
    57         move_A(tmp);
    58         int k = Cantor(tmp);
    59         if(!vis[k]) {
    60             vis[k] = 1;
    61             que.push(tmp);
    62             ans[k] = ans[i] + 'A';
    63         }
    64         tmp = u;
    65         move_B(tmp);
    66         k = Cantor(tmp);
    67         if(!vis[k]) {
    68             vis[k] = 1;
    69             que.push(tmp);
    70             ans[k] = ans[i] + 'B';
    71         }
    72         tmp = u;
    73         move_C(tmp);
    74         k = Cantor(tmp);
    75         if(!vis[k]) {
    76             vis[k] = 1;
    77             que.push(tmp);
    78             ans[k] = ans[i] + 'C';
    79         }
    80     }
    81 }
    82 int main()
    83 {
    84     int a[10];
    85     string s , e;
    86     string start = ("12345678");
    87     BFS(start);//预处理,打表
    88     while(cin >> s >> e)
    89     {
    90         for(int i = 0 ; i < 8 ; i++)//推导开始状态s,到标准开始状态“12345678”
    91                                    //的映射关系,存a中
    92             a[s[i] - '0'] = i + 1;
    93         for(int i = 0 ; i < 8 ; i++)//由映射关系存a及目标状态e推标准的目标状态。
    94             e[i] = a[e[i] - '0'] + '0';
    95         int k = Cantor(e);
    96         cout << ans[k] << endl;
    97     }
    98     return 0;
    99 }
    View Code
  • 相关阅读:
    Pascal's Triangle II
    Pascal's Triangle
    Best Time to Buy and Sell Stock II
    Best Time to Buy and Sell Stock
    Populating Next Right Pointers in Each Node
    path sum II
    Path Sum
    [转载]小波时频图
    [转载]小波时频图
    [转载]Hilbert变换及谱分析
  • 原文地址:https://www.cnblogs.com/mhpp/p/8040017.html
Copyright © 2011-2022 走看看