zoukankan      html  css  js  c++  java
  • 八数码问题(暴力)

    紫书上的程序真是牛逼

    用到了路径寻找之类,还有状态数组,bfs,按坐标寻路的数组。hash,编码解码。STL等

    #include<cstdio>
    #include<cstring>
    #include<set>
    #include<set>
    using namespace std;
    #define maxstate 1000000
    typedef int State[9];
    State st[maxstate] , goal;
    int dist[maxstate];
    
    const int dx[] = {-1, 1, 0, 0};
    const int dy[] = {0, 0, -1, 1};
    
    const int hashsize = 1000003;
    int head[hashsize], next[maxstate];
    void init_lookup_table()  { memset(head,0,sizeof(head)); }
    int hash(State& s){
        int v=0;
        for(int i=0;i<9;i++) v=v*10+s[i];
        return v%hashsize;
    }
    int try_to_insert(int s){
        int h=hash(st[s]);
        int u=head[h];
        while(u){
            if(memcmp(st[u],st[s],sizeof(st[s]))==0) return 0;
            u=next[u];
        }
        next[s]=head[h];
        head[h]=s;
        return 1;
    }
    
    /*set<int> vis;
    void init_lookup_table() { vis.clear(); }
    int try_to_insert(int s){
        int v=0;
        for(int i=0;i<9;i++)  v =v*10 + st[s][i];
        if(vis.count(v)) return 0;
        vis.insert(v);
        return 1;
    }
    */
    /*
    int vis[362880], fact[9];
    void init_lookup_table(){
        fact[0]=1;
        for(int i=1;i<9;i++) fact[i]=fact[i-1]*i;
    }
    
    int try_to_insert(int s){
        int code = 0;
        for(int i=0;i<9;i++){
            int cnt=0;
            for(int j=i+1;j<9;j++) if(st[s][j] < st[s][i]) cnt++;
            code += fact[8-i]*cnt;
    
        }
        if(vis[code]) return 0;
        return vis[code]=1;
    }
    */
    /*
    
    2 6 4 1 3 7 0 5 8
    8 1 5 7 3 6 4 0 2
    */
    int bfs(){
        init_lookup_table();
        int front=1,rear=2;
        while(front < rear){
            State &s = st[front];
            if( memcmp(goal, s, sizeof(s))==0 ) return front;
            int z;
            for(z=0;z<9;z++) if(!s[z]) break;
            int x=z/3,y=z%3;
    //        printf("z=%d x=%d y=%d
    ",z,x,y);
            for(int d=0;d<4;d++){
    
                int newx = x + dx[d];
                int newy = y + dy[d];
                int newz = newx*3 + newy;
    
                if(newx >= 0 && newx <=2 && newy>=0 && newy <=2)
                {
    
                    State& t = st[rear];
                    memcpy(&t,&s,sizeof(s));
                    t[newz] = s[z];
                    t[z]=s[newz];
                    dist[rear] = dist[front] + 1;
                    if(try_to_insert(rear)) {   rear++; }
                }
    
            }
            front++;
        }
        return 0;
    }
    
    int main()
    {
        for(int i=0;i<9;i++) scanf("%d", &st[1][i]);
        for(int i=0;i<9;i++) scanf("%d", &goal[i]);
        int ans = bfs();
    //    printf("%d
    ",ans);
        if(ans > 0 ) printf("%d
    ",dist[ans]);
        else printf("-1
    ");
        return 0;
    }
    


  • 相关阅读:
    01.网页学习阶段、整站分析、规划
    书签搬运
    如何判断两个链表相交及找到第一个相交点
    Windows平台使用git bash管理github中的工程
    二级指针的操作
    结构体的内存对齐
    大端和小端
    剑指Offer——面试题26:复杂链表的复制
    使用editcap命令将ERF格式转换为pcap格式
    如何在STL的map中使用结构体作为键值
  • 原文地址:https://www.cnblogs.com/yutingliuyl/p/7000726.html
Copyright © 2011-2022 走看看