• 【SOUTH CENTRAL USA 1998】 eight


    【题目链接】

    点击打开链接

    【算法】

    这是经典的八数码问题,据说此题不做人生不完整

    这里笔者用的是双向广搜,由于细节较多,笔者花了3h才通过此题

    【代码】

    #include <algorithm>
    #include <bitset>
    #include <cctype>
    #include <cerrno>
    #include <clocale>
    #include <cmath>
    #include <complex>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <ctime>
    #include <deque>
    #include <exception>
    #include <fstream>
    #include <functional>
    #include <limits>
    #include <list>
    #include <map>
    #include <iomanip>
    #include <ios>
    #include <iosfwd>
    #include <iostream>
    #include <istream>
    #include <ostream>
    #include <queue>
    #include <set>
    #include <sstream>
    #include <stdexcept>
    #include <streambuf>
    #include <string>
    #include <utility>
    #include <vector>
    #include <cwchar>
    #include <cwctype>
    #include <stack>
    #include <limits.h>
    
    using namespace std;
    
    struct info {
            int x,y,h;    
            int a[10];        
    };
    
    const int dir[4][2] = {{0,1},{0,-1},{1,0},{-1,0}};
    const int fac[10] = {1,1,2,6,24,120,720,5040,40320,362880};
    
    int i,d,h1,t1,h2,t2;
    int val[10],pre1[500010],pre2[500010],
            step1[500010],step2[500010],visit[500010];
    int s[10] = {0,1,2,3,4,5,6,7,8,9};
    vector<int> path1,path2;
    info q1[500010],q2[500010];
    char x;
    
    int getcantorHash(int a[10]) {
            int i,j,s,ret=0;
            for (i = 1; i < 9; i++) {
                    s = 0;
                    for (j = i + 1; j <= 9; j++) {
                            if (a[i] > a[j])
                                    s++;
                    }
                    ret += s * fac[9-i];
            }
            return ret;
    }
    
    void getpath1(int Hash) {
            int i;
            i = t1;
            while (i > 1) {
                    path1.push_back(step1[q1[i].h]);
                    i = pre1[q1[i].h];            
            }
            reverse(path1.begin(),path1.end());
            path2.push_back(step2[Hash]);
            i = pre2[Hash];
            while (i > 1) {
                    path2.push_back(step2[q2[i].h]);
                    i = pre2[q2[i].h];
            }
    }
    
    void getpath2(int Hash) {
            path1.push_back(step1[Hash]);
            i =    pre1[Hash];
            while (i > 1) {
                    path1.push_back(step1[q1[i].h]);
                    i = pre1[q1[i].h];
            }
            reverse(path1.begin(),path1.end());
            i = t2;
            while (i > 1) {
                    path2.push_back(step2[q2[i].h]);
                    i = pre2[q2[i].h];
            }
    }
    
    bool DBFS() {
            int x,y,tx,ty,Hash;
            int arr[10];
            h1 = t1 = h2 = t2 = 1;
            q1[1].x = (d - 1) / 3 + 1;
            q1[1].y = (d - 1) % 3 + 1;
            q1[1].h = getcantorHash(val);
            memcpy((char*)&q1[1].a[1],(char*)&val[1],sizeof(int)*9);
            step1[getcantorHash(val)] = pre1[getcantorHash(val)] = -1;
            visit[getcantorHash(val)] = 1;
            q2[1].x = q2[1].y = 3;
            q2[1].h = getcantorHash(s);
            memcpy((char*)&q2[1].a[1],(char*)&s[1],sizeof(int)*9);
            step2[getcantorHash(s)] = pre2[getcantorHash(s)] = -1;
             visit[getcantorHash(s)] = 2;
            while ((h1 <= t1) || (h2 <= t2)) {
                    x = q1[h1].x; y = q1[h1].y;
                    for (i = 0; i < 4; i++) {
                            memcpy((char*)&arr[1],(char*)&q1[h1].a[1],sizeof(int)*9);
                            tx = x + dir[i][0];
                            ty = y + dir[i][1];
                            if ((tx <= 0) || (tx > 3) || (ty <= 0) || (ty > 3))
                                    continue;
                            swap(arr[(x-1)*3+y],arr[(tx-1)*3+ty]);
                            Hash = getcantorHash(arr);
                            if (visit[Hash] == 0) {
                                    visit[Hash] = 1;
                                    ++t1;
                                    q1[t1].x = tx;
                                    q1[t1].y = ty;
                                    memcpy((char*)&q1[t1].a[1],(char*)&arr[1],sizeof(int)*9);
                                    q1[t1].h = Hash;
                                    step1[Hash] = i;
                                    pre1[Hash] = h1;
                            }else if (visit[Hash] == 1) {
                                    continue;
                            }else {
                                    ++t1;
                                    q1[t1].h = Hash;
                                    step1[Hash] = i;
                                    pre1[Hash] = h1;
                                    getpath1(Hash);
                                    return true;
                            }
                    }
                    x = q2[h2].x; y = q2[h2].y;
                    for (i = 0; i < 4; i++) {
                            memcpy((char*)&arr[1],(char*)&q2[h2].a[1],sizeof(int)*9);
                            tx = x + dir[i][0];
                            ty = y + dir[i][1];
                            if ((tx <= 0) || (tx > 3) || (ty <= 0) || (ty > 3))
                                    continue;
                            swap(arr[(x-1)*3+y],arr[(tx-1)*3+ty]);
                            Hash = getcantorHash(arr);
                            if (visit[Hash] == 0) {
                                    visit[Hash] = 2;
                                    ++t2;
                                    q2[t2].x = tx;
                                    q2[t2].y = ty;
                                    q2[t2].h = Hash;
                                    memcpy((char*)&q2[t2].a[1],(char*)&arr[1],sizeof(int)*9);
                                    step2[Hash] = i;
                                    pre2[Hash] = h2;
                            }else if (visit[Hash] == 2) {
                                    continue;
                            }else {
                                    ++t2;
                                    q2[t2].h = Hash;
                                    step2[Hash] = i;
                                    pre2[Hash] = h2;
                                    getpath2(Hash);
                                    return true;
                            }
                    }
                    h1++; h2++;
            }
            return false;
    }
    
    void print() {
            int i;
            for (i = 0; i < path1.size(); i++) {
                    switch(path1[i]) {
                            case 0 : putchar('r');
                                             break;
                            case 1 : putchar('l');
                                             break;
                            case 2 : putchar('d');
                                             break;
                            default : putchar('u');
                    }
            }    
            for (i = 0; i < path2.size(); i++) {
                    switch(path2[i]) {
                            case 0 : putchar('l');
                                             break;
                            case 1 : putchar('r');
                                             break;
                            case 2 : putchar('u');
                                             break;
                            default : putchar('d');
                    }
            }
            puts("");
    }
    
    int main() {
            
            for (i = 1; i <= 9; i++) {
                    x = getchar();
                    if (x == 'x') {
                            d = i;
                            val[i] = 9;
                    }else 
                            val[i] = x - '0';
                    getchar(); 
            }
            
            if (DBFS()) print();
            else puts("unsolvable");
            
            return 0;
        
    }
  • 相关阅读:
    剑指 Offer II 001. 整数除法
    conda中如何恢复默认源
    conda中如何创建、查看、删除虚拟环境
    conda中如何移除指定的源
    conda 中如何移除默认源
    清华anaconda开源镜像下载站
    集群环境中使用sbatch提交命令测试
    第三章 消息摘要算法MD5SHAMAC
    第四章 dubbo源码解析目录
    第二章 Base64与URLBase64
  • 原文地址:https://www.cnblogs.com/evenbao/p/9196442.html
Copyright © 2020-2023  润新知