八数码问题。BFS+康托展开
很经典的题。问你怎么移动恢复到初始状态。
一开始上下左右的方向搞错了,而且因为是多种答案(Special Judge)所以WA了好几次,于是一步一步打印出来。终于对了。
跑了360ms。ORZ 0ms的大神。 交HDU 的 1070 就无限TLE 。继续优化好了。(自认为自己的逆康托展开写得不好)
#include<cstdio> #include<cstring> #include<string> #include<queue> #include<algorithm> #include<map> #include<stack> #include<iostream> #include<list> #include<set> #include<cmath> #define INF 0x7fffffff #define eps 1e-8 #define LL long long #define debug puts("==fuck==") #define acfun std::ios::sync_with_stdio(false) using namespace std; int g[4][4]; int b[]= {1,1,2,6,24,120,720,5040,40320}; int a[]= {40320,5040,720,120,24,6,2,1,1}; struct lx { int can; int k; int path; }; int xx[]= {0,0,-1,1}; int yy[]= {1,-1,0,0}; int cantor() { int ans=0; int c=0; bool vis[10]; memset(vis,0,sizeof(vis)); for(int i=0; i<3; i++) for(int j=0; j<3; j++) { int s=0; for(int k=1; k<g[i][j]; k++) if(!vis[k])s++; ans+=s*a[c++]; vis[g[i][j]]=1; } return ans; } int uncantor(int ans) { int t[11]; int top=0; int n=9,s,c; bool vis[10]; memset(vis,0,sizeof(vis)); while(n--) { s=ans/b[n]; c=ans%b[n]; int tm=0; for(int i=1; i<10; i++) { if(!vis[i]) tm++; if(tm==s+1) { s=i; break; } } vis[s]=1; ans=c; t[top++]=s; // printf("%d ",s); } top=0; int be; for(int i=0; i<3; i++) for(int j=0; j<3; j++) { g[i][j]=t[top++]; if(g[i][j]==9) be=i*3+j; } return be; } lx q[1000000]; bool vis[1000000]; void show() { for(int i=0;i<3;i++) { for(int j=0;j<3;j++) printf("%d ",g[i][j]); printf("\n"); } } int bfs() { int e=0,h=0; memset(vis,0,sizeof(vis)); int can=cantor(); q[h].can=can; q[h].path=-1; q[h++].k=-1; vis[can]=1; while(e!=h) { can=q[e++].can; if(can==0) { int k=e-1; char str[1001]; int top=0; while(q[k].path!=-1) { //printf("%d:%d==cantor=%d\n",q[k].path,q[k].k,q[k].can); if(q[k].k==0)str[top++]='r'; else if(q[k].k==1)str[top++]='l'; else if(q[k].k==2)str[top++]='u'; else str[top++]='d'; k=q[k].path; } while(top--) printf("%c",str[top]); printf("\n"); return 0; } int site=uncantor(can); int i=site/3; int j=site%3; for(int k=0; k<4; k++) { int x=i+xx[k]; int y=j+yy[k]; if(x>=3||x<0||y>=3||y<0)continue; swap(g[i][j],g[x][y]); int tmp=cantor(); swap(g[i][j],g[x][y]); if(vis[tmp]) continue; vis[tmp]=1; q[h].can=tmp; q[h].path=e-1; q[h++].k=k; } } puts("unsolvable"); } int main() { char str[11]; while(~scanf("%s",str)) { if(str[0]>='0'&&str[0]<='8') g[0][0]=str[0]-'0'; else g[0][0]=9; for(int i=1; i<9; i++) { scanf("%s",str); if(str[0]>='0'&&str[0]<='8') g[i/3][i%3]=str[0]-'0'; else g[i/3][i%3]=9; } bfs(); } }
原文地址:http://blog.csdn.net/dongshimou/article/details/39202625