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

一、题面

POJ1430

二、分析

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

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

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

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

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

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

$$ \begin{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

猜你喜欢

转载自www.cnblogs.com/dybala21/p/10066566.html