• poj 3131 Cubic Eight-Puzzle 双向广搜 Hash判重


    挺不错的题目,很锻炼代码能力和调试能力~

    题意:初始格子状态固定,给你移动后格子的状态,问最少需要多少步能到达,如果步数大于30,输出-1。


    由于单向搜索状态太多,搜到二十几就会爆了,所以应该想到双向广搜。

    对于每一个格子,我只需要记录上面和前面的格子颜色,因为格子左右移动前面颜色不变上面颜色变了,前后移动的话只是前面和上面的颜色交换了而已,不过写的太挫了。。。应该直接进制压缩一下。。。我还用了两个数来表示前面和上面的颜色,下次把这些搜索题全A了后再回来重新写一下,重写效果也会不错,并不是题目a了这题就好了。


    #include <stdio.h>
    #include <string.h>
    
    #define LL __int64
    
    const int mod = 100007;
    struct HASH{
        int head[mod+10], E, next[222222];
        int v1[222222], v2[222222], c[222222];
    
        void init() {
            memset(head, -1, sizeof(head));
            E = 0;
        }
    
        int gethash(int x,int y) {
            return (((LL)x + y)%mod+mod)%mod;
        }
    
        int isin(int x, int y) {
            int u = gethash(x, y);
            for(int i = head[u];i != -1;i = next[i]) {
                if(v1[i] == x && v2[i] == y) return c[i];
            }
            return -1;
        }
    
        void push(int x, int y, int step) {
            int u = gethash(x, y);
            v1[E] = x;
            v2[E] = y;
            c[E] = step;
            next[E] = head[u];
            head[u] = E++;
        }
    }ha1, ha2;
    
    struct PP{
        int st1, st2;
        int step;
        PP(){}
        PP(int st1, int st2, int step) : st1(st1), st2(st2), step(step) {}
    }cur, to, q[1000002];
    
    int dx[] = {1, -1, 0, 0};
    int dy[] = {0, 0, 1, -1};
    int a[22], b[22], d[2222];
    
    void swap(int &a, int &b) {
        int t = a; a = b; b = t;
    }
    
    void get_zt(int st1, int st2) {
        for(int i = 9;i >= 1;i --)  a[i] = st1%10, st1 /= 10;
        for(int i = 9;i >= 1;i --)  b[i] = st2%10, st2 /= 10;
    }
    
    void get_xy(int &st1, int &st2) {
        st1 = st2 = 0;
        for(int i = 1;i <= 9; i++)  st1 = st1*10+a[i];
        for(int i = 1;i <= 9; i++)  st2 = st2*10+b[i];
    }
    
    bool judge(int go) {
        int ret = 0;
        for(int i = 1;i <= 9; i++)  ret = ret*10+a[i];
        return go == ret;
    }
    
    int getnew(int a, int b) {
        int vis[5], i;
        for(i = 1;i <= 3; i++) vis[i] = 0;
        vis[a]++;vis[b]++;
        for(i = 1;i <= 3; i++)  if(!vis[i]) return i;
    }
    
    int min(int a, int b) {
        return a>b?b:a;
    }
    
    int bfs(int st1,int st2, int go) {
        ha1.init();
        ha1.push(st1, st2, 0);
        int head = 0, tail = 0;
        q[tail++] = PP(st1, st2, 0);
        int i, j, k;
        while(head < tail) {
            cur = q[head++];
            st1 = cur.st1, st2 = cur.st2;
            get_zt(st1, st2);
            int now ;
            for(i = 1;i <= 9; i++)  if(a[i] == 4) {
                now = i; break;
            }
            int x = now/3+1, y = now%3;
            if(y == 0)  y = 3, x--;
            for(i = 0;i < 4; i++) {
                int xx = x+dx[i];
                int yy = y+dy[i];
                if(xx < 1 || xx > 3 || yy < 1 || yy > 3)    continue;
                int then = (xx-1)*3+yy;
                swap(a[now], a[then]);swap(b[now], b[then]);
                if(i < 2) {
                    swap(a[now], b[now]);
                    if(judge(go)) {
                        return cur.step+1;
                    }
                    get_xy(to.st1, to.st2);
                    to.step = cur.step+1;
                    if(ha1.isin(to.st1, to.st2) == -1 && to.step <= 20) {
                        ha1.push(to.st1, to.st2, to.step);
                        if(to.step > 20)   continue;
                        q[tail++] = to;
                    }
                    swap(a[now], b[now]);
                }
                else {
                    a[now] = getnew(a[now], b[now]);
                    if(judge(go)) {
                        return cur.step+1;
                    }
                    get_xy(to.st1, to.st2);
                    to.step = cur.step+1;
                    if(ha1.isin(to.st1, to.st2) == -1 && to.step <= 20) {
                        ha1.push(to.st1, to.st2, to.step);
                        if(to.step > 20)   continue;
                        q[tail++] = to;
                    }
                    a[now] = getnew(a[now], b[now]);
                }
                swap(a[now], a[then]);swap(b[now], b[then]);
            }
        }
        int temp , tot = 0;
        int N = 1<<8;
        for(i = 0;i < N; i++) {
            temp = go;
            for(j = 9;j >= 1; j--)
                a[j] = temp%10 , temp /= 10;
            int id1 = 1, id2 = 0, sum = 0;
            while(id1 <= 9) {
                if(a[id1] == 4) {
                    sum = sum*10+4;
                    id1++;
                    continue;
                }
                if((1<<id2) & i) {
                    for(k = 3;k >= 1; k--)   if(k != a[id1])    break;
                    sum = sum*10+k;
                }
                else {
                    for(k = 1;k <= 3; k++)   if(k != a[id1])    break;
                    sum = sum*10+k;
                }
                id1++, id2++;
            }
            d[tot++] = sum;
        }
        for(i = 0;i < tot; i++){
            int now = ha1.isin(go, d[i]);
            if(now >= 0)    return now;
        }
        int ans = 1111111;
        for(int ii = 0;ii < tot;ii++) {
            ha2.init();
            cur = PP(go, d[ii], 0);
            int head = 0, tail = 0;
            q[tail++] = cur;
            int ok = 0;
            while(head < tail) {
                cur = q[head++];
                st1 = cur.st1, st2 = cur.st2;
                get_zt(st1, st2);
                int now ;
                for(i = 1;i <= 9; i++)  if(a[i] == 4) {
                    now = i; break;
                }
                int x = now/3+1, y = now%3;
                if(y == 0)  y = 3, x--;
                for(i = 0;i < 4; i++) {
                    int xx = x+dx[i];
                    int yy = y+dy[i];
                    if(xx < 1 || xx > 3 || yy < 1 || yy > 3)    continue;
                    int then = (xx-1)*3+yy;
                    swap(a[now], a[then]);swap(b[now], b[then]);
                    if(i < 2) {
                        swap(a[now], b[now]);
                        get_xy(to.st1, to.st2);
                        to.step = cur.step+1;
                        int temp = ha1.isin(to.st1, to.st2);
                        if(temp >= 0)  {
                            ok = 1;
                            ans = min(ans, temp+to.step);continue;
                        }
                        if(ha2.isin(to.st1, to.st2) == -1 && to.step <= 10) {
                            ha2.push(to.st1, to.st2, to.step);
                            q[tail++] = to;
                        }
                        swap(a[now], b[now]);
                    }
                    else {
                        a[now] = getnew(a[now], b[now]);
                        get_xy(to.st1, to.st2);
                        to.step = cur.step+1;
                        int temp = ha1.isin(to.st1, to.st2);
                        if(temp >= 0)  {
                            ok = 1;
                            ans = min(ans, temp+to.step);continue;
                        }
                        if(ha2.isin(to.st1, to.st2) == -1 && to.step <= 10) {
                            ha2.push(to.st1, to.st2, to.step);
                            q[tail++] = to;
                        }
                        a[now] = getnew(a[now], b[now]);
                    }
                    swap(a[now], a[then]);swap(b[now], b[then]);
                    if(ok)  break;
                }
                if(ok)  break;
            }
        }
        if(ans > 30)  return -1;
        return ans;
    }
    
    int main() {
        int i, x, n, m;
        while(scanf("%d%d", &m, &n) != -1 && n) {
            int go = 0, st1 = 0, st2 = 0;
            char ch[2];
            for(i = 1;i <= 9; i++) {
                scanf("%s", ch);
                if(ch[0] == 'W') x = 1;
                else if(ch[0] == 'R')    x = 2;
                else if(ch[0] == 'B')    x = 3;
                else    x = 4;
                go = go*10 + x;
                if(i == (n-1)*3 + m) {
                    st1 = st1*10+4;
                    st2 = st2*10+4;
                }
                else  {
                    st1 = st1*10+1;
                    st2 = st2*10+2;
                }
            }
            if(st1 == go) {
                puts("0"); continue;
            }
            printf("%d
    ", bfs(st1, st2, go));
        }
        return 0;
    }
    



  • 相关阅读:
    模型分离(选做)
    密码保护
    实现搜索功能
    完成个人中心—导航标签
    个人中心标签页导航
    评论列表显示及排序,个人中心显示
    完成评论功能
    从首页问答标题到问答详情页
    运行Junit单测时遇到的问题
    spring定时任务执行两次的原因与解决方法
  • 原文地址:https://www.cnblogs.com/pangblog/p/3239133.html
Copyright © 2020-2023  润新知