zoukankan      html  css  js  c++  java
  • hdu1430魔板

    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

    由于刚做完八数码问题,再来做这题,认为非常简单。可是用bfs超时(原因是多组数据,太多的数据将程序拖到超时),用dbfs就一直wa(原来是反向的搜索不能保证后半段的字典序最小,只能保证后半段的逆序的字典序最小),所以就得不到正确结果。

    百度了一下,原来使用映射+bfs预处理的方法解决的,这样,再多组数据也不怕了。

    将任意的初始状态映射为12345678,在这个过程中得到一个映射函数,目标状态根据这个映射函数,映射为相应的目标状态。(这样子能得到正确答案的原因是,魔板的变换,其实只是位置的变换,数字只是用来标记位置的而已,通过同一种映射关系将初始和目标状态的标记同时该改变,所以仍然能得到正确答案)

    那么所有的数据,都能转化为初始状态为12345678的搜索,那么只要一遍bfs搜索出12345678所有能到达的状态,并记录步骤即可。

     1 #include <stdio.h>
     2 #include <string.h>
     3 #include <queue>
     4 #include <string>
     5 #include <iostream>
     6 using namespace std;
     7 char st[9],ed[9];
     8 int vis[55555];
     9 string ans[55555];
    10 int fac[10] = {1,1,2,6,24,120,720,5040,40320};
    11 int getHash(char *str)//康托展开
    12 {
    13     int i,j,hash = 0,cnt;
    14     for(i=0; i<8; ++i)
    15     {
    16         cnt = 0;
    17         for(j=i+1; j<8; ++j)
    18             if(str[j]<str[i])
    19                 cnt++;
    20         hash += cnt * fac[8-i-1];
    21     }
    22     return hash;
    23 }
    24 struct node
    25 {
    26     char str[8];
    27 };
    28 int d[3][8] = {{7,6,5,4,3,2,1,0},{3,0,1,2,5,6,7,4},{0,6,1,3,4,2,5,7}};
    29 char change[8];
    30 
    31 void bfs()
    32 {
    33     queue<node> q;
    34     node cur,tmp;
    35     int i,j;
    36     for(i=0; i<8; ++i)
    37         cur.str[i] = i + '1';
    38     int hash = getHash(cur.str);
    39     q.push(cur);
    40     vis[hash] = true;
    41     q.push(cur);
    42     while(!q.empty())
    43     {
    44         cur = q.front(); q.pop();
    45         int pHash = getHash(cur.str);
    46         for(i=0; i<3; ++i)
    47         {
    48             for(j=0; j<8; ++j)
    49                 tmp.str[j] = cur.str[d[i][j]];
    50             hash = getHash(tmp.str);
    51             if(vis[hash]) continue;
    52             vis[hash] = true;
    53             ans[hash] = ans[pHash] + (char)('A' + i);
    54             q.push(tmp);
    55         }
    56     }
    57 }
    58 
    59 
    60 int main()
    61 {
    62     bfs();
    63     int i;
    64     while(scanf("%s%s",st,ed)!=EOF)
    65     {
    66         for(i=0; i<8; ++i)
    67             change[st[i]-'1'] =  i+'1';//得到映射函数
    68         for(i=0; i<8; ++i)
    69             ed[i] = change[ed[i]-'1'];//根据映射函数改变目标状态
    70         int hash = getHash(ed);
    71         cout<<ans[hash]<<endl;
    72     }
    73     return 0;
    74 }
  • 相关阅读:
    tomcat解压版环境变量配置
    十天冲刺(第二阶段)
    十天冲刺(第二阶段)
    十天冲刺
    十天冲刺第二阶段()
    十天冲刺(第二阶段)
    十天冲刺(第二阶段)
    十天冲刺(第一阶段)
    十天冲刺(第一阶段)
    十天冲刺(第一阶段)
  • 原文地址:https://www.cnblogs.com/justPassBy/p/4265259.html
Copyright © 2011-2022 走看看