Luogu 1379 八数码难题

吐槽:此题就是一点一点卡过去的
警告:
1、千万不能用dfs搜这种东西(dfs需要遍历所有状态才能找到最优解), 分分钟爆炸
2、写结构体的时候要综合判断&的加和不加

Code:

// luogu-judger-enable-o2
#include <cstdio>
#include <map>
#include <queue>
using namespace std;
typedef long long ll;

const int N = 5;
const int M = 1e6 + 5;
const int dx[] = {1, -1, 0, 0};
const int dy[] = {0, 0, 1, -1};

struct Node {
    int s[N][N], nx, ny, stp;

    inline ll has() {
        ll res = 0, base = 1;
        for(int i = 8; i >= 0; i--, base *= 1ll * 10) {
            int x = i / 3 + 1, y = i % 3 + 1;
            res += 1ll * s[x][y] * base; 
        }
        return res;
    }

 /*   inline void print() {
        for(int i = 1; i <= 3; i++, printf("\n"))
            for(int j = 1; j <= 3; j++)
                printf("%d ", s[i][j]);
        system("pause");
    } */

}f[M], tar;
map <ll, int> vis;

inline bool chk(const Node &now) {
    for(int i = 1; i <= 3; i++)
        for(int j = 1; j <= 3; j++)
            if(now.s[i][j] != tar.s[i][j])
                return 0;
    return 1;
}

inline bool vivid(int x, int y) {
    return x >= 1 && x <= 3 && y >= 1 && y <= 3;
}

inline void swap(int &x, int &y) {
    int t = x;
    x = y;
    y = t;
}

/* void dfs(int x, int y, int stp) {
    if(chk()) { 
        printf("%d\n", stp - 1);
        exit(0);
    }

    ll h = in.has();
    if(vis.count(h)) return;
    vis[h] = 1;
    for(int k = 0; k < 4; k++) {
        int tox = x + dx[k], toy = y + dy[k];
        if(vivid(tox, toy)) {
            swap(in.s[x][y], in.s[tox][toy]);
            
    //        in.print();

            dfs(tox, toy, stp + 1);

            swap(in.s[x][y], in.s[tox][toy]);
        }
    }
    vis[h] = 0;
} */

int bfs() {
    if(chk(f[1])) return 0;
    vis[f[1].has()] = 1;

    for(int head = 0, tail = 1; head <= tail; ) {
        Node out = f[++head];
        
        for(int k = 0; k < 4; k++) {
            int tox = out.nx + dx[k], toy = out.ny + dy[k];

            if(vivid(tox, toy)) {
                Node in = out;
                in.nx = tox, in.ny = toy, in.stp++;
                swap(in.s[out.nx][out.ny], in.s[tox][toy]);

                ll inh = in.has();
                if(!vis.count(inh)) {
                    vis[inh] = 1;
                    if(chk(in)) return in.stp;
                    f[++tail] = in;
                }

            }

        }
    }
}

inline void init() {
    tar.s[1][1] = 1, tar.s[1][2] = 2, tar.s[1][3] = 3;
    tar.s[2][1] = 8, tar.s[2][2] = 0, tar.s[2][3] = 4;
    tar.s[3][1] = 7, tar.s[3][2] = 6, tar.s[3][3] = 5;
}

int main() {
    char str[N << 2];
    scanf("%s", str);
    for(int i = 0; i <= 8; i++) {
        if(str[i] - 48 == 0) f[1].nx = i / 3 + 1, f[1].ny = i % 3 + 1;
        f[1].s[i / 3 + 1][i % 3 + 1] = str[i] - 48;
    }
    f[1].stp = 0;
//    printf("%lld\n", f[1].has());
    init();

//    dfs(sx, sy, 1);
    printf("%d\n", bfs());

    return 0;
}

 

posted @ 2018-08-13 09:35  CzxingcHen  阅读(125)  评论(0编辑  收藏  举报