题目链接:点击打开链接
事情是这样的,我先在TLE无数发之后A了POJ的1077,然后在VJ上看到“原题”,然而,此原题被我TLE5发MLE9发,最后从学长那里学得记录路径的方法之后才过,却原来,这道所谓原题并非原题!!!HDU 的1043和POJ的1077都叫Eight,但是由于HDU上是多组数据POJ上单组,所以POJ上直接正常bfs搜索, HDU上则需要预处理。。。
方法是一样的,对于输入的串,保存成数组,其中x的位置用0代替,最终目标就是123456780
o对了,哈希用的康拓展开,所以12356780对应的康拓展开值是46234
然后正常bfs搜索就好,不过由于时间卡的很死,对于POJ的1077据说双向bfs会更快
然后,HDU的内存不愿多说,MLE之后换了个记录路径的方法
具体见代码:
#include<iostream> #include<cstdio> #include<cstring> #include<string> #include<algorithm> #include<queue> #include<cmath> #include<stdlib.h> #include<cctype> #define mem(a,x) memset(a,x,sizeof(a)) using namespace std; typedef long long ll; const int ans = 46234;//123456780 int fac[] = {1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880}; int ct (int s[]) { int sun = 0, tmp; for (int i = 0; i < 9; i++) { tmp = 0; for (int j = i + 1; j < 9; j++) if (s[j] < s[i]) tmp++; sun += (tmp * fac[9 - i - 1]); } return sun + 1; } bool vis[400000]; struct Node { int g[10]; int x; int st; string p; } h; const int dx[] = { -1, 1, 0, 0}; const int dy[] = {0, 0, -1, 1}; char dd[] = {'u', 'd', 'l', 'r'}; string path; void bfs() { queue<Node>q;mem(vis,0); q.push (h); // vis[h.st] = 1; while (!q.empty() ) { h = q.front(); q.pop(); if (h.st == ans) { path = h.p; return; } int x = h.x / 3; int y = h.x % 3; for (int i = 0; i < 4; ++i) { int xx = x + dx[i]; int yy = y + dy[i]; if (xx >= 0 && yy >= 0 && xx < 3 && yy < 3) { Node nx = h; nx.x = xx * 3 + yy; swap (nx.g[h.x], nx.g[nx.x]); nx.st = ct (nx.g); if (!vis[nx.st]) { if (nx.st == ans) { path = nx.p + dd[i]; return; } vis[nx.st] = 1; nx.p += dd[i]; q.push (nx); } } } } } int main() { char tmp; while (~scanf("%c",&tmp)) { if (tmp == 'x') { h.g[0] = 0; h.x = 0; } else h.g[0] = tmp-48; for (int i = 1; i < 9; ++i) { scanf(" %c",&tmp); if (tmp == 'x') { h.g[i] = 0; h.x = i; } else h.g[i] = tmp - 48; } getchar(); h.st = ct (h.g); h.p.clear(); path = "unsolvable"; bfs(); cout<<path<<endl; } return 0; }
#include<iostream> #include<cstdio> #include<cstring> #include<string> #include<algorithm> #include<queue> #include<cmath> #include<stdlib.h> #include<cctype> #pragma comment(linker, "/STACK:1024000000,1024000000") #define mem(a,x) memset(a,x,sizeof(a)) using namespace std; typedef long long ll; const int dx[] = {-1,1,0,0}; const int dy[] = {0,0,-1,1};//上下左右 const char dd[] = "durl"; const int ans = 46234;//123456780 int fac[] = {1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880}; int ct (int s[]) { int sun = 0, tmp; for (int i = 0; i < 9; i++) { tmp = 0; for (int j = i + 1; j < 9; j++) if (s[j] < s[i]) tmp++; sun += (tmp * fac[9 - i - 1]); } return sun + 1; } struct Node { int g[10]; int x; int st; }h; struct No { int fa; char mo; }moo[400000]; bool vis[400000]; void bfs() { queue<Node>q; q.push(h); vis[h.st] = 1; while (!q.empty()) { h = q.front();q.pop(); int x = h.x / 3; int y = h.x % 3; for (int i = 0; i < 4; ++i) { int xx = x + dx[i]; int yy = y + dy[i]; if (xx >= 0 && yy >= 0 && xx < 3 && yy < 3) { Node nx = h; nx.x = xx * 3 + yy; swap (nx.g[h.x], nx.g[nx.x]); nx.st = ct (nx.g); if (!vis[nx.st]) { vis[nx.st] = 1; moo[nx.st].mo = dd[i]; moo[nx.st].fa = h.st; q.push (nx); } } } } } void init() { for (int i = 0;i < 8;++i) h.g[i] = i+1; h.g[8] = 0; h.x = 8; h.st = ans; moo[ans].fa = -1; bfs(); } int main() { char tmp;init();int s[10]; while (cin>>tmp) { if (tmp == 'x') s[0] = 0; else s[0] = tmp - 48; for (int i = 1;i < 9;++i) { cin>>tmp; if(tmp == 'x') s[i] = 0; else s[i] = tmp - 48; } int st = ct (s); if (st == ans) { puts(""); continue; } if (!vis[st]) printf("unsolvable\n"); else { while (moo[st].fa!=-1) { printf("%c",moo[st].mo); st = moo[st].fa; } puts(""); } } return 0; }