zoukankan      html  css  js  c++  java
  • 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;
    }
  • 相关阅读:
    <<< List<HashMap<String, Object>> 及 HashMap<String, Object> 的用法
    <<< html图片背景平铺
    <<< javascript地址栏,代码
    Linux下常用目录有哪些?分别有什么作用?
    【Linux】Linux下进程间的通信方式
    【Linux】守护进程的定义,作用,创建流程
    【Linux】进程的结构,创建,结束,以及程序转化为的进程的过程
    【Linux】僵尸进程,孤儿进程以及wait函数,waitpid函数(有样例,分析很详细)
    【Linux】多线程同步的四种方式
    【Linux】多线程入门详解
  • 原文地址:https://www.cnblogs.com/shuitiangong/p/12404195.html
Copyright © 2011-2022 走看看