POJ 1077 解题报告
2014-12-13 05:30
253 查看
这道题我是用bfs+hash做的,最好的方法应该是双向bfs或是A*。虽然这学期刚学的AI,但是偷懒,就这样过了吧。
POJ不支持unordered_map,所以得自己写hash,好在比较简单。由于棋盘是9位的(算上空白位置,那一位我用0填充的),所以每个棋盘(即状态值)可以用一个int表示。每个状态需要记录状态值,空白位置,前一个状态值,及怎么从前一个状态值move过来的。这里用的是hash来从状态值获取这些信息。我取的是状态值的前6位作为hash值,建立了一个链式哈希,即将映射到同一个哈希值的所有信息都用一个链表串起来。
另外,这道题是special judge,意思是说答案有多个,不唯一。我的答案就和标准答案不一样,但都是对的。
POJ不支持unordered_map,所以得自己写hash,好在比较简单。由于棋盘是9位的(算上空白位置,那一位我用0填充的),所以每个棋盘(即状态值)可以用一个int表示。每个状态需要记录状态值,空白位置,前一个状态值,及怎么从前一个状态值move过来的。这里用的是hash来从状态值获取这些信息。我取的是状态值的前6位作为hash值,建立了一个链式哈希,即将映射到同一个哈希值的所有信息都用一个链表串起来。
另外,这道题是special judge,意思是说答案有多个,不唯一。我的答案就和标准答案不一样,但都是对的。
1077 | Accepted | 11696K | 688MS | G++ | 3169B |
/* ID: thestor1 LANG: C++ TASK: poj1077 */ #include <iostream> #include <fstream> #include <cmath> #include <cstdio> #include <cstring> #include <limits> #include <string> #include <vector> #include <list> #include <set> #include <map> #include <queue> #include <stack> #include <algorithm> #include <cassert> using namespace std; class State { public: int value, zero, prev, move; State *next; State() {} State(int value, int zero, int prev, int move) : value(value), zero(zero), prev(prev), move(move) {} }; const int MAXN = 1000000; State* Hash[MAXN] = {NULL}; void insert(int value, int zero, int prev, int move) { int key = value % MAXN; State *newstate = new State(value, zero, prev, move); newstate->next = Hash[key]; Hash[key] = newstate; } State* find(int value) { int key = value % MAXN; State *state = Hash[key]; while (state != NULL && state->value != value) { state = state->next; } return state; } // right, left, up, down int dr[4] = {0, 0, -1, 1}, dc[4] = {1, -1, 0, 0}; int getinitialstate(string &state) { int num = 0; int k = 0, z = -1; for (int i = 0; i < state.size(); ++i) { if ('1' <= state[i] && state[i] <= '9') { num = num * 10 + state[i] - '0'; if (z < 0) { k++; } } else if (state[i] == 'x') { num = num * 10; z = k; } } insert(num, z, num, -1); return num; } int next(const int state, int z, int r, int c, int d) { r += dr[d], c += dc[d]; if (0 <= r && r <= 2 && 0 <= c && c <= 2) { int nz = r * 3 + c; int base = pow((double)10, 8 - nz); int digit = (state / base) % 10; int newbase = pow((double)10, 8 - z); int num = state - digit * base + digit * newbase; if (find(num) != NULL) { return -1; } insert(num, nz, state, d); return num; } else { // invalid move return -1; } } int main() { const int finalstate = 123456780; string line; getline(cin, line); int initialstate = getinitialstate(line); // cout << "[debug]initialstate:" << initialstate << endl; queue<int> que; que.push(initialstate); char directions[4] = {'r', 'l', 'u', 'd'}; bool found = false; int state, newstate; while (!que.empty()) { state = que.front(); que.pop(); if (state == finalstate) { found = true; break; } State *s = find(state); assert (s != NULL); int z = s->zero; int r = z / 3, c = z % 3; for (int d = 0; d < 4; ++d) { newstate = next(state, z, r, c, d); // cout << "next " << directions[d] << ", " << newstate << endl; if (newstate > 0) { que.push(newstate); } } } if (found) { stack<char> st; state = finalstate; State *s; while (state != initialstate) { s = find(state); // cout << "[found]state:" << state << ", prev:" << prev[state] << ", move:" << move[state] << endl; st.push(directions[s->move]); state = s->prev; } while (!st.empty()) { cout << st.top(); st.pop(); } cout << endl; } else { cout << "unsolvable" << endl; } return 0; }
相关文章推荐
- poj 1077 解题报告
- POJ 1077 解题报告
- POJ-1129 Channel Allocation 解题报告
- POJ 3074 Sudoku 解题报告(Dancing Link)
- poj1005 解题报告
- Poj Jungle Road (优先队列Prim算法) 解题报告
- POJ 1001 解题报告 Exponentiation
- POJ1118 解题报告JAVA
- poj2381解题报告
- poj解题报告——2234
- POJ1503 解题报告
- POJ 2367 拓扑排序 解题报告
- poj2692 解题报告
- POJ 2513 Colored Sticks (Trie字典树+欧拉通路+并查集) 解题报告
- poj解题报告——2348
- POJ-1730 Perfect Pth Powers 解题报告(数论) 最大开方数
- POJ 2186 解题报告
- POJ-3122 Pie 解题报告(二分) 平分派饼
- POJ3228 Gold Transportation 解题报告【贪心+并查集=Kruskal?】
- [zz]Flip and Shift -- POJ 1063 解题报告