多校第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\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;
}

posted @ 2017-08-27 02:13  伟大的蚊子  阅读(86)  评论(0编辑  收藏  举报