Aizu - 0121

Aizu - 0121

BFS , hash, 康托展开

相似题目 八数码

把每一种状态,用康托计算出来标记

结构体里面套数组的时候,不能直接pust({a,y}) ,因为没有写拷贝构造函数

#include <iostream>
#include <queue>
#include <algorithm>
#include <string>
#include <cstring>
#include <cstdio>
using namespace std;
#define endl '\n'
const int N = 1e6 + 10;
bool st[N];
int fact[10] = {1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880};
int dx[4] = {0,0,1,-1},dy[4] = {1,-1,0,0},b[8];
bool check(int x,int y) {
    return x >= 0 && x < 2 && y >= 0 && y < 4;
}
struct node {
    int a[2][4];
    int step;
};
node start;
int cantor(int a[][4])
{
    int k = 0, res = 0, cnt;
    for(int i = 0; i < 2; i++){
        for(int j = 0;j < 4; j++){
            b[k++] = a[i][j];
        }
    }
    for(int i = 0; i < 8; i++){
        cnt = 0;
        for(int j = i + 1; j < 8;j ++) if(b[j] < b[i]) cnt ++;
        res += cnt*fact[8-i-1];
    }
    return res;
}
bool goal(int a[2][4]) {
    int k = 0;
    for(int i = 0;i < 2; ++i) {
        for(int j = 0;j < 4; ++j) {
            if(k++ != a[i][j]) return 0;
        }
    }
    return 1;
}
int bfs() {
    queue<node> q;
    int x,y;
    start.step = 0;
    q.push(start);
    int tmp = cantor(start.a);
    st[tmp] = 1;
    while(q.size()) {
        node t = q.front();
        q.pop();
        if(goal(t.a)) return t.step;
        for(int i = 0;i < 2; ++i){
            for(int j = 0;j < 4; ++j) {
                if(t.a[i][j] == 0) {
                    x = i,y = j;
                    break;
                }
            }
        }
        for(int i = 0;i < 4; ++i) {
            int nx = x + dx[i],ny = y + dy[i];
            if(check(nx,ny)) {
                swap(t.a[nx][ny],t.a[x][y]);
                tmp = cantor(t.a);
                if(!st[tmp]) {
                    st[tmp] = 1;
                    // 这边不能直接push({t.a,t.step+1})
                    // 因为没有写node(int a[2][4],int step){}这个构造函数
                    t.step ++;
                    q.push(t);
                    t.step --;
                }
                swap(t.a[nx][ny],t.a[x][y]);
            }
        }
    }
    return 0;
}
int main() {
    ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    while(cin >> start.a[0][0]) {
        memset(st,0,sizeof st);
        for(int i = 1;i < 4; ++i) cin >> start.a[0][i];
        for(int i = 0;i < 4; ++i) cin >> start.a[1][i];
        cout << bfs() << endl;
    }
    return 0;
}

构造函数

struct node {
    int a[2][4];
    int step;
    node(){}
    node(int a[2][4],int step){
        for(int i = 0;i < 2; ++i) 
            for(int j = 0;j < 4; ++j)
                this->a[i][j] = a[i][j];
        this->step = step;
    }
};
// 这样就能直接push了
q.push(node(t.a,t.step + 1));
posted @ 2020-03-09 00:29  南风--  阅读(117)  评论(0编辑  收藏  举报