Eight HDU - 1043

题目:3 * 3拼图游戏, 输入一种状态,问你是不是能还原成最终状态。

分析: 1、从最终状态开始逆向bfs
   2、通过数组记录状态,可以用map映射,也可以用康托展开压缩。

代码:

  1 #include <bits/stdc++.h>
  2 using namespace std;
  3 const int maxn = 370000;
  4 int dir[4][2] = {
  5     {-1, 0}, {1, 0}, {0, 1}, {0, -1}
  6 };
  7 struct node
  8 {
  9     int v[11];
 10     int pos;
 11 };
 12 int vis[maxn];
 13 int fa[maxn];
 14 char path[maxn];
 15 int fac[11];
 16 
 17 void ini()
 18 {
 19     fac[0] = 1;
 20     for (int i = 1; i <= 9; i++)
 21         fac[i] = fac[i - 1] * i;
 22 }
 23 
 24 int cantor(int v[])
 25 {
 26     int res = 0;
 27     for (int i = 0; i < 9; i++)
 28     {
 29         int cnt = 0;
 30         for (int j = i + 1; j < 9; j++)
 31             if (v[j] < v[i])
 32                 cnt++;
 33         res += cnt * fac[8 - i];
 34     }
 35     return res;
 36 }
 37 
 38 void bfs()
 39 {
 40     node a;
 41     for (int i = 0; i < 9; i++)
 42         a.v[i] = i + 1;
 43     a.pos = 8;
 44     int statea = cantor(a.v);
 45     queue<node> q;
 46     q.push(a); vis[statea] = 1;
 47     while (!q.empty())
 48     {
 49         node temp = q.front(); q.pop();
 50         int state = cantor(temp.v);
 51         int x = temp.pos / 3, y = temp.pos % 3;
 52         for (int i = 0; i < 4; i++)
 53         {
 54             int xx = x + dir[i][0], yy = y + dir[i][1];
 55             if (xx >= 0 && xx < 3 && yy >= 0 && yy < 3)
 56             {
 57                 node tmp = temp;
 58                 tmp.pos = xx * 3 + yy;
 59                 int t = tmp.v[tmp.pos];
 60                 tmp.v[tmp.pos] = tmp.v[temp.pos];
 61                 tmp.v[temp.pos] = t;
 62                 int state1 = cantor(tmp.v);
 63                 if (!vis[state1])
 64                 {
 65                     q.push(tmp);
 66                     vis[state1] = 1;
 67                     fa[state1] = state;
 68                     if (i == 0)
 69                         path[state1] = 'd';
 70                     else if (i == 1)
 71                         path[state1] = 'u';
 72                     else if (i == 2)
 73                         path[state1] = 'l';
 74                     else path[state1] = 'r';
 75                 }
 76             }
 77         }
 78     }
 79 }
 80 
 81 void print(int now)
 82 {
 83     if (vis[now] == 0)
 84     {
 85         cout << "unsolvable" << endl;
 86         return;
 87     }
 88     while (now)
 89     {
 90         cout << path[now];
 91         now = fa[now];
 92     }
 93     cout << endl;
 94 }
 95 
 96 int main()
 97 {
 98     ini();
 99     string s;
100     bfs();
101     while (getline(cin, s))
102     {
103         int v[11];
104         int cnt = 0;
105         for (int i = 0; i < s.length(); i++)
106         {
107             if (isdigit(s[i]))
108                 v[cnt++] = s[i] - '0';
109             else if (s[i] == 'x')
110                 v[cnt++] = 9;
111         }
112         int now = cantor(v);
113         print(now);
114     }
115 }

 

 


  

posted @ 2019-11-08 00:23  滚烫的青春  阅读(198)  评论(0编辑  收藏  举报