【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;
    
}
原文地址:https://www.cnblogs.com/evenbao/p/9196442.html