UVA 1604:Cubic Eight-Puzzle(模拟,BFS Grade C)
题意:
3*3方格,有一个是空的。其他的每个格子里有一个立方体。立方体最初上下白色,前后红色,左右蓝色。移动的方式为滚。给出初态空的位置,终态上面颜色情况,问最少多少步能到达。如果超过30步不能到达,-1。
思路:
模拟。
另外再加了一个A*优化。就是估计一下。应该还能优化的。感觉像二进制上可以优化。实在不想写了。
代码:
//16:50 #include <cstdio> #include <cstring> #include <queue> #include <map> using namespace std; int heng[6] = {5,3,4,1,2,0}; int shu[6] = {2,4,0,5,1,3}; int go[4][2] = {{0,1},{1,0},{-1,0},{0,-1}}; #define N 4 int ch2num[300]; int que[10000000]; char step[140000000]; int encodeState(int graph[N][N]) { int res = 0; for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { res = (res<<3) + graph[i][j]; } } return res; } void decodeState(int state, int graph[N][N]) { for (int i = 2; i >= 0; i--) { for (int j = 2; j >= 0; j--) { graph[i][j] = state&7; state>>=3; } } } int initState(int x, int y) { int g[N][N]; for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { g[i][j] = 1; } } g[x][y] = 6; return encodeState(g); } int graph[N][N]; int endgraph[N][N]; int h(int state) { int res = 0; for (int i = 2; i >= 0; i--) { for (int j = 2; j >= 0; j--) { if ( ((state>>1)&3) != endgraph[i][j] ) res++; state >>= 3; } } return res-1; } int endState; #define CLEAR_EVERY_3(A) ((A)&0x36db6db) #define ISEND(S) (CLEAR_EVERY_3((S)>>1) == endState) void initEnd() { endState = 0; for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { endState = (endState<<3)+endgraph[i][j]; } } } int main() { ch2num['W'] = 0; ch2num['B'] = 1; ch2num['R'] = 2; ch2num['E'] = 3; int x, y; while (scanf("%d%d", &x, &y) != EOF) { if (x == 0 && y == 0) break; x--;y--; swap(x,y); for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { char tmp[2]; scanf("%s", tmp); endgraph[i][j] = ch2num[tmp[0]]; } } initEnd(); bool finded = false; int ans = 0; int state = initState(x,y); do{ if (ISEND(state)) { finded = true; ans = 0; break; } int hd = 0, tl = 0; que[tl++] = state; memset(step,0,sizeof(step)); step[state] = 1; while (hd < tl) { int now = que[hd++]; if (step[now]-1 >= 30) break; if (h(now)+step[now]-1 > 30) continue; decodeState(now, graph); int si=-1, sj; for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { if (graph[i][j] == 6) { si = i; sj = j; break; } } if (si != -1) break; } if (si == -1) puts("error"); for (int i = 0; i < 4; i++) { int nx = si + go[i][0]; int ny = sj + go[i][1]; if (!(0 <= nx && nx < 3 && 0 <= ny && ny < 3)) continue; swap(graph[nx][ny], graph[si][sj]); if (go[i][0]) { graph[si][sj] = shu[graph[si][sj]]; } else { graph[si][sj] = heng[graph[si][sj]]; } int nstate = encodeState(graph); if (ISEND(nstate)) { finded = true; ans = step[now]; break; } if (go[i][0]) { graph[si][sj] = shu[graph[si][sj]]; } else { graph[si][sj] = heng[graph[si][sj]]; } swap(graph[nx][ny], graph[si][sj]); if (step[nstate] != 0) continue; step[nstate] = step[now]+1; que[tl++] = nstate; } if (finded) break; } }while(0); if (finded) printf("%d\n", ans); else printf("-1\n"); } return 0; }
posted on 2014-10-15 19:33 ShineCheng 阅读(424) 评论(0) 编辑 收藏 举报