zoukankan      html  css  js  c++  java
  • 多校第10场01,双向bfs

    http://blog.csdn.net/cww97/article/details/77616362

    双向dfs也可以过,编程复杂度低一些,不过会刚刚好跑复杂度上限,慢了不少

    时间差的还挺多的

    这里写图片描述

    dfs的时候剪枝都不能有,会蜜汁wa,丢掉就过了

    dfs

    #include <map>
    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    typedef unsigned long long LL;
    const int N = 9;
    const int dx[] = {-1,-1, 1, 1};
    const int dy[] = {-1, 0, 0, 1};
    const int MAXSTEP = 10;
    int ans;
    
    LL po[9][9];
    LL power(int a, int x){
        LL ans = 1, tmp = a;
        for (; x; x>>=1, tmp *=tmp){if (x&1) ans *= tmp;}
        return ans;
    }
    void InitPower(int a, int b){
        for (int i = 1; i <= 6; i++)
            for (int j = 1; j <= i; j++)
                po[i][j] = power(a, b*i+j);
    }
    
    int g[9][9];
    struct ha{
        int g[N][N], cnt, step;
        ha(){}
        ha(int a[N][N], int x, int s){
            memcpy(g,a,sizeof(g));
            cnt = x; step = s;
        }
    };
    map<LL, ha> Hash;
    int H = 0, V;
    LL hashMove(LL hashNum, int x, int y, int cx, int cy){
        return hashNum - (LL)g[x][y] * po[x][y] - (LL)g[cx][cy] * po[cx][cy]
                       + (LL)g[x][y] * po[cx][cy] + (LL)g[cx][cy] * po[x][y];
    }
    
    void InitDfs(int x, int y, LL hashNum, int step){
        if (Hash.find(hashNum) == Hash.end()) Hash[hashNum] = ha(g, ++H, step);
        if (step > MAXSTEP) return;
        for (int i = 0; i < 4; i++){
            int cx = x + dx[i];
            int cy = y + dy[i];
            if (cx<1 || cx>6 || cy<1 || cy>cx) continue;//outbroad
            LL newHash = hashMove(hashNum, x, y, cx, cy);
            //if (Hash.find(newHash) != Hash.end()) continue;//visited
            swap(g[x][y], g[cx][cy]);
            InitDfs(cx, cy, newHash, step + 1);
            swap(g[x][y], g[cx][cy]);
        }
    }
    
    inline void Init(){
        InitPower(7, 17);
        LL hashNum = 0;
        for (int i = 1; i <= 6; i++){
            for (int j = 1; j <= i; j++){
                g[i][j] = i - 1;
                hashNum += g[i][j] * po[i][j];
            }
        }
        Hash.clear();
        InitDfs(1, 1, hashNum, 0);
    }
    
    void dfs(int x, int y, LL hashNum, int step){
        if (Hash.find(hashNum) != Hash.end()){
            ans = min(ans, step + Hash[hashNum].step);
        }
        if (step > MAXSTEP) return;
        for (int i = 0; i < 4; i++){
            int cx = x + dx[i];
            int cy = y + dy[i];
            if (cx<1 || cx>6 || cy<1 || cy>cx) continue;//outbroad
            LL newHash = hashMove(hashNum, x, y, cx, cy);
            swap(g[x][y], g[cx][cy]);
            dfs(cx, cy, newHash, step + 1);
            swap(g[x][y], g[cx][cy]);
        }
    }
    
    //inline void bfs(int sx, int sy, )
    
    int main(){
        //freopen("in.txt", "r", stdin);
        int _, sx, sy;
        Init();
        for (scanf("%d", &_); _--;){
            LL hashNum = 0;
            for (int i = 1; i <= 6; i++){
                for (int j = 1; j <= i; j++){
                    scanf("%d", &g[i][j]);
                    hashNum += g[i][j] * po[i][j];
                    if (g[i][j] == 0) {sx = i, sy = j;}
                }
            }
            ans = 33; V = 0;
            dfs(sx, sy, hashNum, 0);
            //bfs(sx, sy, hashNum);
            if (ans <= 20) printf("%d
    ", ans);
            else puts("too difficult");
        }
        return 0;
    }
    

    bfs

    #include <map>
    #include <queue>
    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    typedef unsigned long long LL;
    const int N = 9;
    const int dx[] = {-1,-1, 1, 1};
    const int dy[] = {-1, 0, 0, 1};
    const int MAXSTEP = 10;
    
    LL po[9][9];
    LL power(int a, int x){
        LL ans = 1, tmp = a;
        for (; x; x>>=1, tmp *=tmp){if (x&1) ans *= tmp;}
        return ans;
    }
    void InitPower(int a, int b){
        for (int i = 1; i <= 6; i++)
            for (int j = 1; j <= i; j++)
                po[i][j] = power(a, b*i+j);
    }
    
    int g[9][9];
    struct ha{
        int g[N][N], x, y, step;
        LL hashNum;
        ha(){}
        ha(int a[N][N], int _x, int _y,  int s, LL h){
            memcpy(g, a, sizeof(g));
            x = _x; y = _y;
            step = s;
            hashNum = h;
        }
        void print(){
            printf("hash: (%d, %d), s = %d, ", x, y, step);
            cout << hashNum <<endl;
        }
        bool operator < (const ha &b) const{
            return hashNum < b.hashNum;
        }
    };
    map<LL, ha> Hash;
    map<LL, int> vis;
    int V;
    LL hashMove(LL hashNum, int x, int y, int cx, int cy){
        return hashNum - (LL)g[x][y] * po[x][y] - (LL)g[cx][cy] * po[cx][cy]
                       + (LL)g[x][y] * po[cx][cy] + (LL)g[cx][cy] * po[x][y];
    }
    
    void InitBfs(LL hashNum){
        Hash.clear();
        queue<ha> Q;
        Q.push(ha(g, 1, 1, 0, hashNum));
        for (; !Q.empty();){
            ha h = Q.front(); Q.pop();
            int x = h.x, y = h.y, step = h.step;
            if (step > MAXSTEP) return;
            hashNum = h.hashNum;
            if (Hash.find(hashNum) != Hash.end()) continue;
            Hash[hashNum] = ha(g, x, y, step, hashNum);
            memcpy(g, h.g, sizeof(g));
            for (int i = 0; i < 4; i++){
                int cx = x + dx[i];
                int cy = y + dy[i];
                //printf("(%d, %d) -> (%d, %d)
    ", x, y, cx, cy);
                if (cx<1 || cx>6 || cy<1 || cy>cx) continue;//outbroad
                LL newHash = hashMove(hashNum, x, y, cx, cy);
                swap(g[x][y], g[cx][cy]);
                Q.push(ha(g, cx, cy, step+1, newHash));
                swap(g[x][y], g[cx][cy]);
            }
        }
    }
    
    inline void Init(){
        InitPower(7, 17);
        LL hashNum = 0;
        for (int i = 1; i <= 6; i++){
            for (int j = 1; j <= i; j++){
                g[i][j] = i - 1;
                hashNum += g[i][j] * po[i][j];
            }
        }
        InitBfs(hashNum);
    }
    
    int bfs(int sx, int sy, LL hashNum){
        //Hash[136260025190489192LL].print();
        //cout << hashNum <<endl;
        vis.clear();
        V = 0;
        queue<ha> Q;
        for (; !Q.empty();) Q.pop();
        Q.push(ha(g, sx, sy, 0, hashNum));
        for (; !Q.empty();){
            ha h = Q.front(); Q.pop();
            int x = h.x, y = h.y, step = h.step;
            //if (step <= 5) {ha(g, x, y, step, hashNum).print();}
            if (step > MAXSTEP) return 22;
            hashNum = h.hashNum;
            //h.print();
            if (vis.find(hashNum) != vis.end()) continue;
            vis[hashNum] = ++V;
            if (Hash.find(hashNum) != Hash.end())
                return step + Hash[hashNum].step;
            memcpy(g, h.g, sizeof(g));
            for (int i = 0; i < 4; i++){
                int cx = x + dx[i];
                int cy = y + dy[i];
                //printf("(%d, %d) -> (%d, %d)
    ", x, y, cx, cy);
                if (cx<1 || cx>6 || cy<1 || cy>cx) continue;//outbroad
                LL newHash = hashMove(hashNum, x, y, cx, cy);
                swap(g[x][y], g[cx][cy]);
                Q.push(ha(g, cx, cy, step+1, newHash));
                swap(g[x][y], g[cx][cy]);
            }
        }
        return 22;
    }
    
    int main(){
        //freopen("in.txt", "r", stdin);
        int _, sx, sy;
        Init();
        for (scanf("%d", &_); _--;){
            LL hashNum = 0;
            for (int i = 1; i <= 6; i++){
                for (int j = 1; j <= i; j++){
                    scanf("%d", &g[i][j]);
                    hashNum += g[i][j] * po[i][j];
                    if (g[i][j] == 0) {sx = i, sy = j;}
                }
            }
            int ans = bfs(sx, sy, hashNum);
            if (ans <= 20) printf("%d
    ", ans);
            else puts("too difficult");
        }
        return 0;
    }
    
    
  • 相关阅读:
    在win7系统下安装把Ubuntu17.04安装在另一个硬盘开机无法进入Ubuntu问题的一种解决办法。【转】
    快速上手Ubuntu之安装篇——安装win7,Ubuntu16.04双系统【转】
    win7 64位系统与Ubuntu14.04 64位系统双系统安装【转】
    kernel中对文件的读写【学习笔记】【原创】
    快速解决Android中的selinux权限问题【转】
    Android如何配置init.rc中的开机启动进程(service)【转】
    linux内核驱动中对文件的读写 【转】
    很好的 DHCP协议与dhcpcd分析【转】
    android DHCP流程【转】
    Android wifi 从连接态自动断开的解决办法(dhcp导致)【转】
  • 原文地址:https://www.cnblogs.com/cww97/p/12349349.html
Copyright © 2011-2022 走看看