【题目链接】
【算法】
这是经典的八数码问题,据说此题不做人生不完整
这里笔者用的是双向广搜,由于细节较多,笔者花了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;
}