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编辑  收藏  举报

导航