多校第10场01,双向bfs

来源:互联网 发布:航天税控开票软件 编辑:程序博客网 时间:2024/06/06 03:59

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\n", 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)\n", 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)\n", 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\n", ans);        else puts("too difficult");    }    return 0;}