八数码 康托 逆康托 哈希 双解码 双向广搜

#include <cstdio>  //
#include <cstring>  //
#include <string>  //
#include <set>  //
#include <queue>  //
#include <algorithm>  //
#include <map>  //
#include <stack>  // 
using namespace std;  //

struct Node {  //
    int status;  //
    int pos;  //

 Node(int s = 0, int p = 0) { // 
        status = s;  //
        pos = p;  //
    }  //
};  //初始化; 

const int MAXN = 2 * 3 * 4 * 5 * 6 * 7 * 8 * 9 + 10;  //328890
int jie[10] = {1, 1 ,2 ,6 ,24 ,120 ,720, 5040, 40320 ,362880};  //
int dirx[] = {-1, 1, 0, 0};  //
int diry[] = {0, 0, -1, 1};  //
int father[2][MAXN];  //存储二个队列的已经存过的值 
bool vis[2][MAXN];    //标记 
queue<Node> q[2];  //

bool InRange(int x, int y) {  //判断超出边界       
    return x >= 0 && x < 3 && y >= 0 && y < 3;  //
}  //
  //
int Hash(string s) {  //
    int ans = 0;  //
    for (int i = 0; i < 9; ++i) {  //
        int  rev = 0;  //
        for (int j = i + 1; j < 9; ++j) {  //康托展开 
            if (s[i] > s[j]) ++rev;  //
        }  //
        ans += rev * jie[8 - i];  //
    }  //
    return ans;  //
}  

string RevHash(int val) {  //逆康托 
    string ans = "";  //
    bool tag[10] = {};  //
    for (int i = 0; i < 9; ++i) {  //
        int tNum = val / jie[8 - i] + 1;  //
        for (int j = 1; j <= tNum; ++j) {  //
            if (tag[j]) ++tNum;  //
        }  //
        val %= jie[8 - i];  //
        ans += tNum + '0';  // 
        tag[tNum] = true;  //
    }  //
    return ans;  //
}  //

void PutPath(int mid) {  // 
    stack<char> path;  // 

    int a = mid;  // a是康托值 
    while (father[0][a] != a) 
    { //如果现在的a不是目的a继续; 
        string s = RevHash(a);//目标转码  
        string fs = RevHash(father[0][a]);//上一个康拓殖的转码  

        int pos, fpos;  // 
        for (int i = 0; i < s.size(); ++i) {//  
            if (s[i] == '9') pos = i;//  
            if (fs[i] == '9') fpos = i;//  
        }  // 

        if (pos / 3 == fpos / 3) //x 同x 
        {  
            if (pos % 3 < fpos % 3)
             {  
                path.push('l');  
             }
            else 
            {  
                path.push('r');  
            }  
       } 
       else 
       {  
           if (pos / 3 < fpos / 3) 
           {  
                path.push('u');  
           } 
           else
            {  
                path.push('d');  
            }  
        } 

        a = father[0][a];  
    }  

    while (!path.empty()) { // 
        putchar(path.top());  //输出 
        path.pop();//  
    }  // 

    int b = mid;  // 
    while (father[1][b] != b) { // 
        string s = RevHash(b);  // 
        string ss = RevHash(father[1][b]);//  

        int pos, spos;  // 
        for (int i = 0; i < s.size(); ++i) { // 
            if (s[i] == '9') pos = i;  // 
            if (ss[i] == '9') spos = i;  // 
        }  // 
        if (pos / 3 == spos / 3) {  // 
            if (pos % 3 < spos % 3) { // 
                putchar('r');  // 
            } else {  // 
                putchar('l');//  
            }  // 
        } else { // 
            if (pos / 3 < spos / 3) { // 
                putchar('d');  // 
            } else {  // 
                putchar('u');// 
            }  // 
        }  // 
        b = father[1][b];//  
    }  // 
    putchar('\n'); // 
}  // 

bool Expand(int id) {  // 
    Node h = q[id].front(); q[id].pop();  //
    int x = h.pos / 3, y = h.pos % 3;  // 

    for (int i = 0; i < 4; ++i) {  // 
        int nx = x + dirx[i];  // 
        int ny = y + diry[i];  // 
        int npos = nx * 3 + ny;  //

        if (!InRange(nx, ny)) continue;  //

        string ns = RevHash(h.status);  //串 
        swap(ns[h.pos], ns[npos]);  //交换 
        int hashVal = Hash(ns);  //数值 

        if (!vis[id][hashVal]) {  //没有的话 
            father[id][hashVal] = h.status;//上一个 ,fate存的是上一个上一个,,, 
            q[id].push(Node(hashVal, npos));//下一个  
            vis[id][hashVal] = true;  //标记 

            if (vis[1 - id][hashVal]) {  //如果有的话; 
                PutPath(hashVal);  //找路径 
                return true; //结束 
            }  
        }  
    }  
    return false; // 继续 
}  

bool DBFS(int st, int ed, int pos) {  // 
    memset(vis, 0, sizeof vis);  //
    memset(father, 0, sizeof father);  ///
    for (int i = 0; i < 2; ++i)  //
        while (!q[i].empty()) q[i].pop();  //初始化 

    father[0][st] = st;  // 
    father[1][ed] = ed;  // 

    vis[0][st] = true;  // 
    vis[1][ed] = true;  // 

    q[0].push(Node(st, pos));  // 
    q[1].push(Node(ed, 8));  // 

    while (!q[0].empty() && !q[1].empty())// 
     {  // 
        if (q[0].size() <= q[1].size())// 
        {  // 
            if (Expand(0)) return true; // 
        } // 
        else// 
        {  // 
            if (Expand(1)) return true;//  
        }  // 
     }  // 

    for (int i = 0; i < 2; ++i)  // 
        while (!q[i].empty())  // 
            if (Expand(i)) // 
            return true;  // 

    return false;  // 
}  

int main() { //

    char s[100];  
    while (gets(s) != NULL) {  
        int len = strlen(s), pos = 0;  // 
        string ma = "";  // 
        for (int i = 0; i < len; ++i) {  // 
            if (s[i] == 'x') {  // 
                pos = ma.size();  // 
                s[i] = '9';  // 转化成123456789 
            }  // 
            if (s[i] != ' ') {  // 
                ma += s[i];  // 
            }  // 
        }  // 
        int rev = 0;  
        for (int i = 0; i < 9; ++i) {  //
            if (ma[i] == '9') continue;  //
            for (int j = i + 1; j < 9; ++j) {  //逆序判断 
                if (ma[i] > ma[j]) ++rev;  //
            }  //
        }  //
        if (rev & 1) puts("unsolvable"); // 
        else DBFS(Hash(ma), 0, pos);  //传输的都是康托值 0为123456789,ma为输入的那个; pos 为x的位置 
    }  // 
    return 0;  // 
}  // 
1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看REaDME.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值