hdoj1043 Eight(逆向BFS+打表+康拓展开)
Posted frankchen831x
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了hdoj1043 Eight(逆向BFS+打表+康拓展开)相关的知识,希望对你有一定的参考价值。
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1043
思路:
由于自己对康拓展开用的太少,看到这个题没想到康拓展开,最开始打算直接转换为数字,但太占内存了,又想到可以将状态存进set,后来查了一下发现原来是考察康拓展开。另外就是需要打表预处理,这样快很多。BFS部分就是已知终点,从终点逆向搜索,并存每个状态的上一个状态以及操作,以便输出。
坑点:输入是多组输入,POJ那道题才是一组输入,卡在这一上午T_T。
有一组输入为12345678x,需要特殊处理,不能不输出,可以输出“lr”。
1 #include<bits/stdc++.h> 2 using namespace std; 3 4 const int maxn=1e6+5; 5 struct node{ 6 char a[9]; 7 int x,y; 8 int cnt; 9 }tmp; 10 11 int fac[9]; 12 int vis[maxn]; 13 char path[maxn]; 14 int pre[maxn]; 15 int go[4][2]={-1,0,0,1,1,0,0,-1}; 16 17 void init(){ 18 fac[0]=fac[1]=1; 19 for(int i=2;i<9;i++) fac[i]=fac[i-1]*i; 20 } 21 22 int cantour(char *s){ 23 int ans=0,k; 24 for(int i=0;i<8;i++){ 25 k=0; 26 for(int j=i+1;j<9;j++) 27 if(s[j]<s[i]) k++; 28 ans+=k*fac[8-i]; 29 } 30 return ans; 31 } 32 33 void bfs(){ 34 queue<node> q; 35 for(int i=0;i<8;i++) 36 tmp.a[i]=i+1+‘0‘; 37 tmp.a[8]=‘0‘; 38 tmp.x=2,tmp.y=2,tmp.cnt=cantour(tmp.a); 39 vis[tmp.cnt]=1; 40 q.push(tmp); 41 path[tmp.cnt]=-1; 42 while(!q.empty()){ 43 node now=q.front();q.pop(); 44 int nx=now.x,ny=now.y,ncnt=now.cnt; 45 for(int i=0;i<4;i++){ 46 int xx=nx+go[i][0],yy=ny+go[i][1]; 47 if(xx<0||xx>2||yy<0||yy>2) continue; 48 strcpy(tmp.a,now.a); 49 swap(tmp.a[nx*3+ny],tmp.a[xx*3+yy]); 50 tmp.x=xx,tmp.y=yy,tmp.cnt=cantour(tmp.a); 51 if(!vis[tmp.cnt]){ 52 vis[tmp.cnt]=1; 53 pre[tmp.cnt]=ncnt; 54 if(i==0) path[tmp.cnt]=‘d‘; 55 else if(i==1) path[tmp.cnt]=‘l‘; 56 else if(i==2) path[tmp.cnt]=‘u‘; 57 else path[tmp.cnt]=‘r‘; 58 q.push(tmp); 59 } 60 } 61 } 62 } 63 64 void print(int f){ 65 while(path[f]!=-1){ 66 printf("%c",path[f]); 67 f=pre[f]; 68 } 69 printf(" "); 70 } 71 72 int main(){ 73 char c[9],ch; 74 int f; 75 init(); 76 bfs(); 77 while(scanf(" %c",&ch)!=EOF){ 78 if(ch==‘x‘) c[0]=‘0‘; 79 else c[0]=ch; 80 for(int i=1;i<9;i++){ 81 scanf(" %c",&ch); 82 if(ch==‘x‘) c[i]=‘0‘; 83 else c[i]=ch; 84 } 85 f=cantour(c); 86 if(path[f]==-1) printf("lr "); 87 else if(!vis[f]) printf("unsolvable "); 88 else print(f); 89 } 90 return 0; 91 }
以上是关于hdoj1043 Eight(逆向BFS+打表+康拓展开)的主要内容,如果未能解决你的问题,请参考以下文章
HDU 1043 Eight八数码解题思路(bfs+hash 打表 IDA* 等)