http://acm.hdu.edu.cn/showproblem.php?pid=1043
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 x
1 2 3 4 1 2 3 4 1 2 3 4 1 2 3 4 5 6 7 8 5 6 7 8 5 6 7 8 5 6 7 8 9 x 10 12 9 10 x 12 9 10 11 12 9 10 11 12 13 14 11 15 13 14 11 15 13 14 x 15 13 14 15 x r-> d-> r->
2 3 4 1 5 x 7 6 8
ullddrurdllurdruldr
/** hdu1043 bfs 题目大意:类似一个九宫格问题,给定一个3*3的棋盘,有1~8个数字,一个x。给定初始位置状态,最终到达同一指定状态,x棋子可以和其上下左右的棋子进行交换顺序,求出一种给定的合法序列 从初始装太可以到达给定状态 解题思路:基本的方法是利用康拓展开记录状态,从初始状态到给定状态进行bfs搜索。但是这样写有多少组输入就要进行多少次bfs比较费时。因为题目给定的是同一个目标状态,所以我们进行倒着搜 搜索出所有的状态,这样只进行一次bfs就可以了 */ #include <string.h> #include <algorithm> #include <string> #include <iostream> #include <stdio.h> #include <queue> using namespace std; const int maxn=1e6+5; const int INF=0x3f3f3f3f; struct note { char s[3][3]; int x,y; int can; }; int father[maxn],path[maxn],vis[maxn]; int dx[]= {-1,1,0,0}; int dy[]= {0,0,-1,1}; int fac[10]; void init() { fac[0]=1; fac[1]=1; for(int i=2; i<10; i++) { fac[i]=fac[i-1]*i; } memset(vis,0,sizeof(vis)); memset(father,-1,sizeof(father)); } int canton(char s[3][3]) { int a[9]; int cur=0; for(int i=0; i<3; i++) { for(int j=0; j<3; j++) { a[cur++]=s[i][j]-'0'; } } int ans=0; for(int i=0; i<9; i++) { int cnt=0; for(int j=i+1; j<9; j++) { if(a[j]<a[i])cnt++; } ans+=cnt*fac[8-i]; } return ans; } void bfs(note ss) { queue<note>q; int ca=canton(ss.s); vis[ca]=1; father[ca]=-2; ss.can=ca; q.push(ss); while(!q.empty()) { note st=q.front(),en; q.pop(); for(int i=0; i<4; i++) { int x=st.x+dx[i]; int y=st.y+dy[i]; if(x>=0&&x<3&&y>=0&&y<3) { en=st; swap(en.s[x][y],en.s[st.x][st.y]); int t=canton(en.s); if(!vis[t]) { vis[t]=1; en.x=x; en.y=y; en.can=t; q.push(en); father[t]=st.can; path[t]=i; } } } } } void print(int x) { if(father[x]==-2)return; int t=path[x]; if(t==0)putchar('d'); else if(t==1)putchar('u'); else if(t==2)putchar('r'); else putchar('l'); print(father[x]); } int main() { init(); note s; int cnt=1; for(int i=0; i<3; i++) { for(int j=0; j<3; j++) { s.s[i][j]=cnt+'0',cnt++; } } s.s[2][2]='0'; s.x=s.y=2; bfs(s); char ss[3][3]; char sss[100]; while(gets(sss)!=NULL) { int cur=0; for(int i=0; i<3; i++) { for(int j=0; j<3; j++) { while(sss[cur]==' '&&sss[cur]!='\0')cur++; if(sss[cur]<='9'&&sss[cur]>='0') ss[i][j]=sss[cur++]; else if(sss[cur]=='x') { ss[i][j]='0'; cur++; } } } int sta=canton(ss); if(father[sta]==-1) printf("unsolvable"); else print(sta); cout<<endl; } return 0; }