• 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
    ", ans);
            else printf("-1
    ");
        }
        return 0;
    }
  • 相关阅读:
    内核驱动系列中断和定时器
    apue2 阅读笔记第四章
    apue2 阅读笔记 第五章
    apue2阅读笔记 第6.7章
    再试试windows7版得writer
    内核驱动系列内核调试方法
    apue2 阅读笔记第三章
    杂谈关于代码库
    know everything about something
    React的父子传值(父传子)
  • 原文地址:https://www.cnblogs.com/shinecheng/p/4027154.html
Copyright © 2020-2023  润新知