• HDU_1430 魔板 【BFS+康托展开+置换】


    一、题面

    POJ1430

    二、分析

    该题与之前做的八数码不同,它是一个2*4的棋盘,并且没有空的区域。这样考虑的情况是很少的,依然结合康托展开,这时康托展开最多也只乘7的阶乘,完全可以BFS先预处理一遍。

    这里需要注意,在处理的时候,仔细读题,他的二维变一维的顺序是顺时针一遍读过来的。

    预处理完后,这里需要用一个小技巧,就是置换。

    $$ egin{pmatrix} 3 & 2 & 1 & 4 & 5 & 6 & 7 & 8\1 & 2 & 3 & 4 & 5 & 6 & 7 & 8 \ end{pmatrix} $$

    上面使用的例子是$32145678$,然后相当于把它移到了和$12345678$一个起跑线上,这样做的好处就是我们预处理的答案能够适用所有情况。

    假设目标状态是$87654321$,这样把目标状态置换成与上面对应的即可。

    $$ egin{pmatrix} 8 & 7 & 6 & 5 & 4 & 3 & 2 & 1\8 & 7 & 6 & 5 & 4 & 1 & 2 & 3 \ end{pmatrix} $$

    这样就可以直接输出结果了。

    三、AC代码

      1 #include <cstdio>
      2 #include <iostream>
      3 #include <fstream>
      4 #include <cstring>
      5 #include <queue>
      6 #include <algorithm>
      7 
      8 using namespace std;
      9 
     10 const int MAXN = 40321;
     11 const int fac[] = {1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880};    //factorial
     12 bool visit[MAXN];
     13 struct Node
     14 {
     15     int m[8];
     16     int cat;
     17 };
     18 char op[] = "ABC";
     19 string ans[MAXN];
     20 
     21 void A(Node &t)
     22 {
     23     std::reverse(t.m , t.m+8);
     24 }
     25 
     26 void B(Node &t)
     27 {
     28     int temp = t.m[3];
     29     for(int i = 3; i > 0; i--)
     30     {
     31         t.m[i] = t.m[i-1];
     32     }
     33     t.m[0] = temp;
     34     temp = t.m[4];
     35     for(int i = 4; i < 7; i++)
     36     {
     37         t.m[i] = t.m[i+1];
     38     }
     39     t.m[7] = temp;
     40 }
     41 
     42 void C(Node &t)
     43 {
     44     int temp = t.m[1];
     45     t.m[1] = t.m[6];
     46     t.m[6] = t.m[5];
     47     t.m[5] = t.m[2];
     48     t.m[2] = temp;
     49 }
     50 
     51 int Cantor(int s[])
     52 {
     53     int t, ans = 1;
     54     for(int i = 0; i < 8; i++)
     55     {
     56         t = 0;
     57         for(int j = i+1; j < 8; j++)
     58         {
     59             if(s[j] < s[i])
     60                 t++;
     61         }
     62         ans += t*fac[7-i];
     63     }
     64     return ans;
     65 }
     66 
     67 void bfs()
     68 {
     69     memset(visit, 0, sizeof(visit));
     70     Node t;
     71     for(int i = 0; i < 8; i++)
     72         t.m[i] = i+1;
     73     t.cat = Cantor(t.m);
     74     queue<Node> Q;
     75     ans[t.cat] = "";
     76     visit[t.cat] = 1;
     77     Q.push(t);
     78     while(!Q.empty())
     79     {
     80         Node p = Q.front();
     81         Q.pop();
     82         for(int i = 0; i < 3; i++)
     83         {
     84             t = p;
     85             switch(i)
     86             {
     87                 case 0: A(t);break;
     88                 case 1: B(t);break;
     89                 case 2: C(t);break;
     90             }
     91             t.cat = Cantor(t.m);
     92             if( !visit[t.cat] )
     93             {
     94                 
     95                 ans[t.cat] = ans[p.cat]+op[i];
     96                 visit[t.cat] = 1;
     97                 Q.push(t);
     98             }
     99         }
    100     }
    101     
    102 }
    103 
    104 int main()
    105 {
    106     //freopen("input.txt", "r", stdin);
    107     //freopen("out.txt", "w", stdout);
    108     char s[10];
    109     int a[10] = {0}, b[8] = {0};
    110     bfs();
    111     while(scanf("%s", s)!=EOF)
    112     {
    113         for(int i = 0; i < 8; i++)
    114         {
    115             a[s[i] - '0'] = i+1;
    116         }
    117         scanf("%s", s);
    118         for(int i = 0; i < 8; i++)
    119         {
    120             b[i] = a[s[i] - '0'];
    121         }
    122         cout << ans[Cantor(b)] << endl;
    123     }
    124     return 0;
    125 }
    View Code
  • 相关阅读:
    构建之法阅读笔记01
    软件工程个人作业01
    第一个PSP0级
    java实现课表的增加
    软件工程概论01
    异常处理
    流与文件课件课后作业1计算容量
    第九周课堂测试
    第八周动手动脑
    JAVA项目中常用的异常知识点总结
  • 原文地址:https://www.cnblogs.com/dybala21/p/10066566.html
Copyright © 2020-2023  润新知