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 }