POJ - 1077 - Eight(bfs)

题目链接:https://vjudge.net/problem/POJ-1077

题目大意:八数码,问你能不能把当前状态转换成12345678x,可以就输出转换步骤,不行就输出unsolvable。

  经典的八数码题,只是在普通的bfs基础上用上了康托展开,用map,string的可能会t

#include<set>
#include<map>
#include<list>
#include<stack>
#include<queue>
#include<cmath>
#include<cstdio>
#include<cctype>
#include<string>
#include<vector>
#include<climits>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#define endl '\n'
#define max(a, b) (a > b ? a : b)
#define min(a, b) (a < b ? a : b)
#define mst(a) memset(a, 0, sizeof(a))
#define IOS ios::sync_with_stdio(false)
#define _test printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n")
using namespace std;
typedef long long ll;
typedef pair<int, int> P;
typedef pair<ll, ll> P2;
const double pi = acos(-1.0);
const double eps = 1e-7;
const ll MOD =  1000000007LL;
const int INF = 0x3f3f3f3f;
const int _NAN = -0x3f3f3f3f;
const int NIL = -1;
template<typename T> void read(T &x){
    x = 0;char ch = getchar();ll f = 1;
    while(!isdigit(ch)){if(ch == '-')f*=-1;ch=getchar();}
    while(isdigit(ch)){x = x*10+ch-48;ch=getchar();}x*=f;
}
const int maxn = 1e6+10;
int vis[maxn], start[9], ed[9] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
const int dir[4][2] = {1,0, -1,0, 0,-1, 0,1};
const int fact[10] = {1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880};
struct Q {
    int x, y, kase, state[9];
    char ans[30];
};
int cantor(int num[], int n) { //用康托展开计算判断当前状态
    int sum = 0;
    for (int i = 0; i<n; ++i) {
        int cnt = 0;
        for (int j = i+1; j<n; ++j)
            if (num[i]>num[j]) ++cnt;
        sum += cnt*fact[n-i-1];
    }
    return vis[sum] ? false : vis[sum] = true;
}
bool checker(int* num) { //和目标状态比较
    for (int i = 0; i<9; ++i)
        if (num[i]!=ed[i]) return false;
    return true;
}
Q bfs(int w) {
    queue<Q> qe;
    Q t = {w/3, w%3}; //转换成坐标形式
    cantor(start, 9);
    t.kase = 0;
    memcpy(t.state, start, sizeof(start));
    qe.push(t);
    while(!qe.empty()) {
        t = qe.front();
        qe.pop();
        if (checker(t.state)) return t;
        for (int i = 0; i<4; ++i) {
            int xx = t.x+dir[i][0], yy = t.y+dir[i][1];
            if (xx>=0&&xx<3&&yy>=0&&yy<3) {
                Q t2 = t;
                t2.x = xx, t2.y = yy;
                t2.ans[t2.kase++] += "dulr"[i];
                swap(t2.state[t2.x*3+t2.y], t2.state[t.x*3+t.y]);
                if (checker(t2.state)) return t2;
                if (cantor(t2.state, 9)) qe.push(t2);
            }
        }
    }
    t = {-1, -1};
    return t;
}
int main(void) {
    char s[2]; int pos;
    for (int i = 0; i<9; ++i) {
        scanf("%s", s);
        if (s[0]=='x') s[0] = '9', pos=i; //记录下起始位置
        start[i] = s[0]-'0';
    }
    Q res = bfs(pos);
    if (res.x == -1) printf("unsolvable\n");
    else
        printf("%s\n", res.ans);
    return 0;
}

 

posted @ 2020-03-03 19:49  shuitiangong  阅读(118)  评论(0编辑  收藏  举报