Luogu 1379 八数码难题
吐槽:此题就是一点一点卡过去的
警告:
1、千万不能用dfs搜这种东西(dfs需要遍历所有状态才能找到最优解), 分分钟爆炸
2、写结构体的时候要综合判断&的加和不加
Code:
// luogu-judger-enable-o2 #include <cstdio> #include <map> #include <queue> using namespace std; typedef long long ll; const int N = 5; const int M = 1e6 + 5; const int dx[] = {1, -1, 0, 0}; const int dy[] = {0, 0, 1, -1}; struct Node { int s[N][N], nx, ny, stp; inline ll has() { ll res = 0, base = 1; for(int i = 8; i >= 0; i--, base *= 1ll * 10) { int x = i / 3 + 1, y = i % 3 + 1; res += 1ll * s[x][y] * base; } return res; } /* inline void print() { for(int i = 1; i <= 3; i++, printf("\n")) for(int j = 1; j <= 3; j++) printf("%d ", s[i][j]); system("pause"); } */ }f[M], tar; map <ll, int> vis; inline bool chk(const Node &now) { for(int i = 1; i <= 3; i++) for(int j = 1; j <= 3; j++) if(now.s[i][j] != tar.s[i][j]) return 0; return 1; } inline bool vivid(int x, int y) { return x >= 1 && x <= 3 && y >= 1 && y <= 3; } inline void swap(int &x, int &y) { int t = x; x = y; y = t; } /* void dfs(int x, int y, int stp) { if(chk()) { printf("%d\n", stp - 1); exit(0); } ll h = in.has(); if(vis.count(h)) return; vis[h] = 1; for(int k = 0; k < 4; k++) { int tox = x + dx[k], toy = y + dy[k]; if(vivid(tox, toy)) { swap(in.s[x][y], in.s[tox][toy]); // in.print(); dfs(tox, toy, stp + 1); swap(in.s[x][y], in.s[tox][toy]); } } vis[h] = 0; } */ int bfs() { if(chk(f[1])) return 0; vis[f[1].has()] = 1; for(int head = 0, tail = 1; head <= tail; ) { Node out = f[++head]; for(int k = 0; k < 4; k++) { int tox = out.nx + dx[k], toy = out.ny + dy[k]; if(vivid(tox, toy)) { Node in = out; in.nx = tox, in.ny = toy, in.stp++; swap(in.s[out.nx][out.ny], in.s[tox][toy]); ll inh = in.has(); if(!vis.count(inh)) { vis[inh] = 1; if(chk(in)) return in.stp; f[++tail] = in; } } } } } inline void init() { tar.s[1][1] = 1, tar.s[1][2] = 2, tar.s[1][3] = 3; tar.s[2][1] = 8, tar.s[2][2] = 0, tar.s[2][3] = 4; tar.s[3][1] = 7, tar.s[3][2] = 6, tar.s[3][3] = 5; } int main() { char str[N << 2]; scanf("%s", str); for(int i = 0; i <= 8; i++) { if(str[i] - 48 == 0) f[1].nx = i / 3 + 1, f[1].ny = i % 3 + 1; f[1].s[i / 3 + 1][i % 3 + 1] = str[i] - 48; } f[1].stp = 0; // printf("%lld\n", f[1].has()); init(); // dfs(sx, sy, 1); printf("%d\n", bfs()); return 0; }