[kuangbin带你飞]专题二-搜索进阶-B-Eight II
2017-04-06 01:45
274 查看
ACM模版
这里就考到了我们一个替换的思维,让我们想想,如果这些模块不是数字,而是颜色,那么我们会对其进行编号,所以,只要保证初始和终止状态模块对应关系不错,我们就可以随意对其进行编号。
打个比方,题中所给数据:
5 6 4
1 7 8
X 2 3
作为初始状态所对应的终止状态为:
7 5 6
8 X 4
1 2 3
那么,我们可以对起始和终止状态都进行替换,将5替换为1,6替换为2,4替换为3,1替换为4,7替换为5,8替换为6,2替换为7,3替换为8,那么则对应变为:
1 2 3
4 5 6
X 7 8
和
5 1 2
6 X 3
4 7 8
可以发现,同时替换后,起始和终止状态模块对应关系依然不变,所以我们可以将所有的初始(或终止)状态归为九种,分别是 target[][]中所存储状态,这里默认 X 为 0 。
Eight II 和 Eight 的差别也就在于此了,对了,需要注意求出步数最少且字典序最小,那么则需要注意 bfs 里的循环方向问题,先考虑向下(d),再考虑向左(l),其次考虑向右(r),最后考虑向上(u),GG!
描述
题解
这道题和 Eight 相似,不过终止状态不唯一了,但是我们可以总结为9种状态,每种状态的核心差别是 X 的位置,所以我们需要打九个表,那么问题来了,怎么才能通过给定的终止(或初始)状态在这九个表中找到对应的关系呢?这里就考到了我们一个替换的思维,让我们想想,如果这些模块不是数字,而是颜色,那么我们会对其进行编号,所以,只要保证初始和终止状态模块对应关系不错,我们就可以随意对其进行编号。
打个比方,题中所给数据:
5 6 4
1 7 8
X 2 3
作为初始状态所对应的终止状态为:
7 5 6
8 X 4
1 2 3
那么,我们可以对起始和终止状态都进行替换,将5替换为1,6替换为2,4替换为3,1替换为4,7替换为5,8替换为6,2替换为7,3替换为8,那么则对应变为:
1 2 3
4 5 6
X 7 8
和
5 1 2
6 X 3
4 7 8
可以发现,同时替换后,起始和终止状态模块对应关系依然不变,所以我们可以将所有的初始(或终止)状态归为九种,分别是 target[][]中所存储状态,这里默认 X 为 0 。
Eight II 和 Eight 的差别也就在于此了,对了,需要注意求出步数最少且字典序最小,那么则需要注意 bfs 里的循环方向问题,先考虑向下(d),再考虑向左(l),其次考虑向右(r),最后考虑向上(u),GG!
代码
#include <iostream> #include <cstdio> #include <cstring> #include <queue> using namespace std; const int MAXN = 362882 + 10; // 9! + 10 int cnt; int sta_contor[10]; int target[10][10] = { {0, 1, 2, 3, 4, 5, 6, 7, 8}, {1, 0, 2, 3, 4, 5, 6, 7, 8}, {1, 2, 0, 3, 4, 5, 6, 7, 8}, {1, 2, 3, 0, 4, 5, 6, 7, 8}, {1, 2, 3, 4, 0, 5, 6, 7, 8}, {1, 2, 3, 4, 5, 0, 6, 7, 8}, {1, 2, 3, 4, 5, 6, 0, 7, 8}, {1, 2, 3, 4, 5, 6, 7, 0, 8}, {1, 2, 3, 4, 5, 6, 7, 8, 0} }; struct { int pre; char dir; int steps; } vis[10][MAXN]; int fac[10]; // 记录当前棋盘状态和x的位置 struct node { int a[10]; int x; }; // hash-康拓展开式 int hash_cantor(int a[]) { int ans = 0; for (int i = 0; i < 9; i++) { int temp = 0; for (int j = i + 1; j < 9; j++) { if (a[j] < a[i]) { temp++; } } ans += temp * fac[8 - i]; } return ans; } char str[5] = "dlru"; int dir[4][2] = {{1, 0}, {0, -1}, {0, 1}, {-1, 0}}; void bfs(int op, node end) { queue<node> Q; Q.push(end); while (!Q.empty()) { node n = Q.front(); Q.pop(); int n_contor = hash_cantor(n.a); int pos = n.x; for (int i = 0; i < 4; i++) { int x = n.x / 3; int y = n.x % 3; int x_ = x + dir[i][0]; int y_ = y + dir[i][1]; if (x_ >= 0 && x_ < 3 && y_ >= 0 && y_ < 3) { int cnt = x_ * 3 + y_; swap(n.a[cnt], n.a[pos]); n.x = cnt; int v = hash_cantor(n.a); if (vis[op][v].pre == -1 && v != sta_contor[op]) { vis[op][v].dir = str[i]; vis[op][v].pre = n_contor; vis[op][v].steps = vis[op][n_contor].steps + 1; Q.push(n); } n.x = pos; swap(n.a[cnt], n.a[pos]); } } } } void init() { fac[0] = fac[1] = 1; for (int i = 2; i < 10; i++) { fac[i] = fac[i - 1] * i; } for (int i = 0; i < 9; i++) { for (int j = 0; j < MAXN; j++) { vis[i][j].pre = -1; } } node end; for (int i = 0; i < 9; i++) { swap(end.a, target[i]); end.x = i; sta_contor[i] = hash_cantor(end.a); bfs(i, end); } } int main() { init(); int T; cin >> T; for (int cs = 1; cs <= T; cs++) { node ed; char s[10]; int tag[10]; scanf("%s", s); for (int i = 0, j = 1; i < 9; i++) { if (s[i] == 'X') { cnt = i; } else { tag[s[i] - '0'] = j++; } } scanf("%s", s); for (int i = 0; i < 9; i++) { if (s[i] == 'X') { ed.a[i] = 0; } else { ed.a[i] = tag[s[i] - '0']; } } int end_contor = hash_cantor(ed.a); int res_contor = end_contor; string s_ = ""; while (vis[cnt][res_contor].pre != -1) { s_ += vis[cnt][res_contor].dir; res_contor = vis[cnt][res_contor].pre; } printf("Case %d: %d\n", cs, vis[cnt][end_contor].steps); for (int i = (int)s_.length() - 1; i >= 0; i--) { printf("%c", s_[i]); } puts(""); } return 0; }
相关文章推荐
- [kuangbin带你飞]专题二 搜索进阶 I
- 【算法系列学习】[kuangbin带你飞]专题二 搜索进阶 D - Escape (BFS)
- [kuangbin带你飞]专题二 搜索进阶 I - A计划(HDU 2102)
- [kuangbin带你飞]专题二 搜索进阶 A - Eight
- [kuangbin带你飞]专题二-搜索进阶-A-Eight
- [kuangbin带你飞]专题二 搜索进阶 D
- [kuangbin带你飞]专题二-搜索进阶-D-Escape
- [kuangbin带你飞]专题二 搜索进阶
- 【算法系列学习三】[kuangbin带你飞]专题二 搜索进阶 之 A-Eight 反向bfs打表和康拓展开
- [kuangbin带你飞]专题二-搜索进阶-C-哈密顿绕行世界问题
- [kuangbin带你飞]专题二 搜索进阶 E
- [kuangbin带你飞]专题二 搜索进阶 I - A计划
- [kuangbin带你飞]专题二 搜索进阶 C - 哈密顿绕行世界问题(HDU 2181)
- [kuangbin带你飞]专题二 搜索进阶 G
- [kuangbin带你飞]专题二 搜索进阶 题解(康托展开、映射、迭代加深)
- [kuangbin带你飞]专题二 搜索进阶 C
- [kuangbin带你飞]专题二 搜索进阶 A(康拓展开+bfs)
- [kuangbin带你飞]专题一 简单搜索-C - Catch That Cow POJ - 3278
- [kuangbin带你飞]专题一 简单搜索K - 迷宫问题(POJ 3984)
- [kuangbin带你飞]专题一 简单搜索 G - Shuffle'm Up poj 3087