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