1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 x
1 2 3 4 1 2 3 4 1 2 3 4 1 2 3 4 5 6 7 8 5 6 7 8 5 6 7 8 5 6 7 8 9 x 10 12 9 10 x 12 9 10 11 12 9 10 11 12 13 14 11 15 13 14 11 15 13 14 x 15 13 14 15 x r-> d-> r->
2 3 4 1 5 x 7 6 8
ullddrurdllurdruldr
先膜拜下这位大神http://www.cnblogs.com/goodness/archive/2010/05/04/1727141.html
总结了此题的八境界。
用string直接保存路径的暴力广搜+hash,结果自然是tle。
#include<stdio.h> #include<iostream> #include<algorithm> #include<map> #include<queue> #include<stack> #include<vector> #include<cstdlib> #include<functional> #include<string> using namespace std; const int maxn = 4; const int cnt = 3; int a[cnt][cnt], c[maxn << 2], f[500000], x, y, z; int b[maxn] = { -1, 1, 0, 0 }; int d[maxn] = { 0, 0, 1, -1 }; char e[maxn + 1] = { "udrl" }; class abc { public: int a[cnt][cnt], x, y, z; string s; abc(){}; abc(int a[cnt][cnt], int x, int y, int z, string s) { this->s = s; this->x = x; this->y = y; this->z = z; memcpy(this->a, a, sizeof(this->a)); } }; bool insert() { char s[2]; for (int i = 0; i < 3;i++) for (int j = 0; j < 3;j++) if (scanf("%s", s) == EOF) return false; else { a[i][j] = min(9, s[0] - '0'); if (a[i][j] == 9) x = i, y = j; } return true; } int get(int a[cnt][cnt]) { int tot = 0; for (int i = 0; i < 9; i++) { int k = 0; for (int j = 0; j < i; j++) if (a[j / 3][j % 3]>a[i / 3][i % 3]) k++; tot += k * c[i]; } return tot; } void bfs(int a[cnt][cnt]) { memset(f, 0, sizeof(f)); queue<abc> p; z = get(a); p.push(abc(a, x, y, z, "")); f[z] = 1; while (!p.empty()) { abc q = p.front(); p.pop(); if (q.z == 0) { cout << q.s << endl; return; } for (int i = 0; i < maxn; i++) { x = q.x + b[i]; y = q.y + d[i]; if (x>=0 && x<cnt && y>=0 && y < cnt) { swap(q.a[q.x][q.y], q.a[x][y]); z = get(q.a); if (!f[z]){ f[z] = 1; p.push(abc(q.a, x, y, z, q.s + e[i])); } swap(q.a[q.x][q.y], q.a[x][y]); } } } printf("unsolvable\n"); } int main() { for (int i = c[0] = 1; i < 9; i++) c[i] = c[i - 1] * i; while (insert()) bfs(a); return 0; }从终点开始搜回去然后hash判重,打表输出。hdu 500ms ac
#include<stdio.h> #include<iostream> #include<algorithm> #include<map> #include<queue> #include<stack> #include<vector> #include<cstdlib> #include<functional> #include<string> using namespace std; const int maxn = 4; const int cnt = 3; int a[cnt][cnt], c[maxn << 2], x, y, z; int b[maxn] = { 0, -1, 0, 1 }; int d[maxn] = { 1, 0, -1, 0 }; char e[maxn + 1] = { "ldru" }; string f[500000]; class abc { public: int a[cnt][cnt], x, y, z; abc(){}; abc(int a[cnt][cnt], int x, int y, int z) { this->x = x; this->y = y; this->z = z; memcpy(this->a, a, sizeof(this->a)); } }; bool insert() { char s[2]; for (int i = 0; i < 3;i++) for (int j = 0; j < 3;j++) if (scanf("%s", s) == EOF) return false; else a[i][j] = min(9, s[0] - '0'); return true; } int get(int a[cnt][cnt]) { int tot = 0; for (int i = 0; i < 9; i++) { int k = 0; for (int j = 0; j < i; j++) if (a[j / 3][j % 3]>a[i / 3][i % 3]) k++; tot += k * c[i]; } return tot; } void bfs(int a[cnt][cnt]) { memset(f, 0, sizeof(f)); queue<abc> p; z = get(a); p.push(abc(a, 2, 2, z)); f[z] = ""; while (!p.empty()) { abc q = p.front(); p.pop(); for (int i = 0; i < maxn; i++) { x = q.x + b[i]; y = q.y + d[i]; if (x>=0 && x<cnt && y>=0 && y < cnt) { swap(q.a[q.x][q.y], q.a[x][y]); z = get(q.a); if (!f[z][0]){ f[z] = e[i] + f[q.z]; p.push(abc(q.a, x, y, z)); } swap(q.a[q.x][q.y], q.a[x][y]); } } } } int main() { for (int i = c[0] = 1; i < 9; i++) { c[i] = c[i - 1] * i; a[(i - 1) / 3][(i - 1) % 3] = i; a[2][2] = 9; } bfs(a); while (insert()) if (f[get(a)][0]) cout << f[get(a)] << endl; else printf("unsolvable\n"); return 0; }双广,hdu 爆内存 poj 125ms
#include<stdio.h> #include<iostream> #include<algorithm> #include<map> #include<queue> #include<stack> #include<vector> #include<cstdlib> #include<functional> #include<string> using namespace std; const int maxn = 4; const int cnt = 3; int a[cnt][cnt], c[maxn << 2], x, y, z; int b[maxn] = { -1, 0, 1, 0 }; int d[maxn] = { 0, -1, 0, 1 }; int zz[2]; char e[2][maxn + 1] = { "uldr", "drul" }; string f[2][400000]; class abc { public: int a[cnt][cnt], x, y, z, id; abc(){}; abc(int a[cnt][cnt], int x, int y, int z, int id) { this->id = id; this->x = x; this->y = y; this->z = z; memcpy(this->a, a, sizeof(this->a)); } }; bool insert() { char s[2]; for (int i = 0; i < 3;i++) for (int j = 0; j < 3;j++) if (scanf("%s", s) == EOF) return false; else { a[i][j] = min(9, s[0] - '0'); if (a[i][j] == 9) x = i, y = j; } return true; } int get(int a[cnt][cnt]) { int tot = 0; for (int i = 0; i < 9; i++) { int k = 0; for (int j = 0; j < i; j++) if (a[j / 3][j % 3]>a[i / 3][i % 3]) k++; tot += k * c[i]; } return tot; } void bfs(int a[cnt][cnt]) { memset(f, 0, sizeof(f)); queue<abc> p; zz[0] = get(a); p.push(abc(a, x, y, zz[0], 0)); f[0][zz[0]] = ""; for (int i = 0; i < 9; i++) a[i / 3][i % 3] = i + 1; zz[1] = get(a); p.push(abc(a, 2, 2, zz[1], 1)); f[1][zz[1]] = ""; while (!p.empty()) { abc q = p.front(); p.pop(); for (int i = 0; i < maxn; i++) { x = q.x + b[i]; y = q.y + d[i]; if (x>=0 && x<cnt && y>=0 && y < cnt) { swap(q.a[q.x][q.y], q.a[x][y]); z = get(q.a); if (!f[q.id][z][0]){ if (q.id) f[q.id][z] = e[q.id][i] + f[q.id][q.z]; else f[q.id][z] = f[q.id][q.z] + e[q.id][i]; if (f[1 - q.id][z][0] || z == zz[1 - q.id]) { cout << f[0][z] << f[1][z] << endl; return; } else p.push(abc(q.a, x, y, z, q.id)); } swap(q.a[q.x][q.y], q.a[x][y]); } } } printf("unsolvable\n"); } int main() { for (int i = c[0] = 1; i < 9; i++) c[i] = c[i - 1] * i; while (insert()) bfs(a); return 0; }
#include<stdio.h> #include<iostream> #include<algorithm> #include<map> #include<queue> #include<stack> #include<vector> #include<cstdlib> #include<functional> #include<string> using namespace std; const int maxn = 4; const int cnt = 3; int a[cnt][cnt], c[maxn << 2], x, y, z, g, h; int b[maxn] = { -1, 0, 1, 0 }; int d[maxn] = { 0, -1, 0, 1 }; char e[maxn + 1] = { "uldr" }; int ins[400000][2]; string f[400000]; struct abc { int a[cnt][cnt], x, y, z; abc(){}; abc(int a[cnt][cnt], int x, int y, int z) { this->x = x; this->y = y; this->z = z; memcpy(this->a, a, sizeof(this->a)); } }; struct cmp{ bool operator()(const abc&a, const abc&b) { return ins[a.z][1] + ins[a.z][2] > ins[b.z][1] + ins[b.z][2]; } }; bool insert() { char s[2]; for (int i = 0; i < 3; i++) for (int j = 0; j < 3; j++) if (scanf("%s", s) == EOF) return false; else { a[i][j] = min(9, s[0] - '0'); if (a[i][j] == 9) x = i, y = j; } return true; } int get(int a[cnt][cnt]) { int tot = 0; for (int i = 0; i < 9; i++) { int k = 0; for (int j = 0; j < i; j++) if (a[j / 3][j % 3]>a[i / 3][i % 3]) k++; tot += k * c[i]; } return tot; } int find(int a[cnt][cnt]) { int tot = 0; for (int i = 0; i < 8; i++) if (a[i / 3][i % 3] != i + 1) tot++; return tot; } void bfs(int a[cnt][cnt]) { memset(f, 0, sizeof(f)); memset(ins, 0, sizeof(ins)); priority_queue<abc, vector<abc>, cmp> p; z = get(a); f[z] = ""; p.push(abc(a, x, y, z)); ins[z][0] = 0; ins[z][1] = find(a); while (!p.empty()) { abc q = p.top(); p.pop(); if (!q.z){ cout << f[q.z] << endl; return; } for (int i = 0; i < maxn; i++) { x = q.x + b[i]; y = q.y + d[i]; if (x >= 0 && x<cnt && y >= 0 && y < cnt) { swap(q.a[q.x][q.y], q.a[x][y]); z = get(q.a); g = ins[q.z][0] + 1; h = find(q.a); if ((!(ins[z][0] + ins[z][1]))|| ins[z][0] + ins[z][1]>h + g) { f[z] = f[q.z] + e[i]; ins[z][0] = g; ins[z][1] = h; p.push(abc(q.a, x, y, z)); } swap(q.a[q.x][q.y], q.a[x][y]); } } } printf("unsolvable\n"); } int main() { for (int i = c[0] = 1; i < 9; i++) c[i] = c[i - 1] * i; while (insert()) bfs(a); return 0; }A*+哈希+曼哈顿距离+优先队列 poj 47ms
#include<stdio.h> #include<iostream> #include<algorithm> #include<map> #include<queue> #include<stack> #include<vector> #include<cstdlib> #include<functional> #include<string> using namespace std; const int maxn = 4; const int cnt = 3; int a[cnt][cnt], c[maxn << 2], x, y, z, g, h; int b[maxn] = { -1, 0, 1, 0 }; int d[maxn] = { 0, -1, 0, 1 }; char e[maxn + 1] = { "uldr" }; int ins[400000][2]; string f[400000]; struct abc { int a[cnt][cnt], x, y, z; abc(){}; abc(int a[cnt][cnt], int x, int y, int z) { this->x = x; this->y = y; this->z = z; memcpy(this->a, a, sizeof(this->a)); } }; struct cmp{ bool operator()(const abc&a, const abc&b) { return ins[a.z][1] + ins[a.z][2] > ins[b.z][1] + ins[b.z][2]; } }; bool insert() { char s[2]; for (int i = 0; i < 3; i++) for (int j = 0; j < 3; j++) if (scanf("%s", s) == EOF) return false; else { a[i][j] = min(9, s[0] - '0'); if (a[i][j] == 9) x = i, y = j; } return true; } int get(int a[cnt][cnt]) { int tot = 0; for (int i = 0; i < 9; i++) { int k = 0; for (int j = 0; j < i; j++) if (a[j / 3][j % 3]>a[i / 3][i % 3]) k++; tot += k * c[i]; } return tot; } int find(int a[cnt][cnt]) { int tot = 0; for (int i = 0; i < cnt; i++) for (int j = 0; j < cnt; j++) { int x = (a[i][j] - 1) / 3; int y = (a[i][j] - 1) % 3; tot += abs(x - i) + abs(y - j); } return tot; } void bfs(int a[cnt][cnt]) { memset(f, 0, sizeof(f)); memset(ins, 0, sizeof(ins)); priority_queue<abc, vector<abc>, cmp> p; z = get(a); f[z] = ""; p.push(abc(a, x, y, z)); ins[z][0] = 0; ins[z][1] = find(a); while (!p.empty()) { abc q = p.top(); p.pop(); if (!q.z){ cout << f[q.z] << endl; return; } for (int i = 0; i < maxn; i++) { x = q.x + b[i]; y = q.y + d[i]; if (x >= 0 && x<cnt && y >= 0 && y < cnt) { swap(q.a[q.x][q.y], q.a[x][y]); z = get(q.a); g = ins[q.z][0] + 1; h = find(q.a); if ((!(ins[z][0] + ins[z][1])) || ins[z][0] + ins[z][1]>h + g) { f[z] = f[q.z] + e[i]; ins[z][0] = g; ins[z][1] = h; p.push(abc(q.a, x, y, z)); } swap(q.a[q.x][q.y], q.a[x][y]); } } } printf("unsolvable\n"); } int main() { for (int i = c[0] = 1; i < 9; i++) c[i] = c[i - 1] * i; while (insert()) bfs(a); return 0; }
#include<stdio.h> #include<iostream> #include<algorithm> #include<map> #include<queue> #include<stack> #include<vector> #include<cstdlib> #include<functional> #include<string> using namespace std; const int maxn = 3; const int maxd = 100; int a[maxn][maxn], x, y, f; int b[2][maxn + 1] = { 0, -1, 0, 1, 1, 0, -1, 0 }; char d[maxn + 2] = { "ruld" }; char ans[maxd]; map<char, char> M; bool insert() { char s[2]; for (int i = 0; i < maxn; i++) for (int j = 0; j < maxn; j++) if (scanf("%s", s) == EOF) return false; else { a[i][j] = min(9, s[0] - '0'); if (a[i][j] == 9) x = i, y = j; } return true; } bool check(int a[maxn][maxn]) { for (int i = 0; i < maxn; i++) for (int j = 0; j < maxn; j++) if (a[i][j] != i + i + i + j + 1) return false; return true; } int get() { int tot = 0; for (int i = 0; i < maxn; i++) for (int j = 0; j < maxn; j++) { if (a[i][j] < 9) tot += abs((a[i][j] - 1) / 3 - i) + abs((a[i][j] - 1) % 3 - j); } return tot; } void dfs(int h, int ax, int ay, int deep, int max_d) { if (deep + h >= max_d || f) return; if (check(a)) { ans[deep] = '\0'; f = 1; return; } int bx, by, H = 0, g; for (int i = 0; i <= maxn; i++) { if (deep&&M[d[i]] == ans[deep - 1]) continue; bx = ax + b[0][i]; by = ay + b[1][i]; if (0 <= bx&&bx < maxn && 0 <= by&&by < maxn) { ans[deep] = d[i]; g = a[bx][by] - 1; H = h - abs(g / 3 - bx) - abs(g % 3 - by); H = H + abs(g / 3 - ax) + abs(g % 3 - ay); swap(a[ax][ay], a[bx][by]); dfs(H, bx, by, deep + 1, max_d); if (f) return; swap(a[ax][ay], a[bx][by]); } } } int cansolve() { int tot = 0; for (int i = 0; i < 9; i++) for (int j = 0; j < i; j++) if (a[i / 3][i % 3] != 9 && a[j / 3][j % 3] != 9) if (a[i / 3][i % 3] < a[j / 3][j % 3]) tot++; return 1 - tot % 2; } int main() { M['r'] = 'l'; M['l'] = 'r'; M['d'] = 'u'; M['u'] = 'd'; while (insert()) { f = 0; if (!cansolve()) { printf("unsolvable\n"); continue; } for (int i = 1; !f; i++) dfs(get(), x, y, 0, i); if (f) printf("%s\n", ans); } return 0; }