蓝桥杯 九宫格 基础bfs+康托展开
http://lx.lanqiao.org/problem.page?gpid=T42
【细心一点~】
历届试题 九宫重排
时间限制:1.0s 内存限制:256.0MB
问题描述
如下面第一个图的九宫格中,放着 1~8 的数字卡片,还有一个格子空着。与空格子相邻的格子中的卡片可以移动到空格中。经过若干次移动,可以形成第二个图所示的局面。
![](http://lx.lanqiao.org/RequireFile.do?fid=qYebaGed)
![](http://lx.lanqiao.org/RequireFile.do?fid=HQ3JFM72)
我们把第一个图的局面记为:12345678.
把第二个图的局面记为:123.46758
显然是按从上到下,从左到右的顺序记录数字,空格记为句点。
本题目的任务是已知九宫的初态和终态,求最少经过多少步的移动可以到达。如果无论多少步都无法到达,则输出-1。
我们把第一个图的局面记为:12345678.
把第二个图的局面记为:123.46758
显然是按从上到下,从左到右的顺序记录数字,空格记为句点。
本题目的任务是已知九宫的初态和终态,求最少经过多少步的移动可以到达。如果无论多少步都无法到达,则输出-1。
输入格式
输入第一行包含九宫的初态,第二行包含九宫的终态。
输出格式
输出最少的步数,如果不存在方案,则输出-1。
样例输入
12345678.
123.46758
123.46758
样例输出
3
样例输入
13524678.
46758123.
46758123.
样例输出
22
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<vector> 5 #include<queue> 6 #include<algorithm> 7 using namespace std; 8 9 int fac[10]; 10 int dir[4][2]= {{1,0},{-1,0},{0,1},{0,-1}}; 11 bool vis[1000000]; 12 char s1[10],s2[10]; 13 const int l=9; 14 struct node 15 { 16 char s[10]; 17 int loc, num, step; 18 }; 19 queue<node > q; 20 21 void get() 22 { 23 fac[0]=1; 24 for(int i=1; i<9; i++) 25 fac[i]=fac[i-1]*i; 26 27 } 28 29 int gethash(char s[],int l) 30 { 31 int sum=0; 32 for(int i=0; i<l; i++) 33 { 34 int p=0; 35 for(int j=i+1; j<l; j++) 36 if(s[i]>s[j]) 37 p++; 38 sum+=p*fac[8-i]; 39 }//printf("hash %s %d\n",s,sum); 40 return sum+1; 41 42 } 43 44 int bfs(node s) 45 { 46 while(q.size()) 47 q.pop(); 48 q.push(s); 49 while(!q.empty()) 50 { 51 node t; 52 t=q.front(); 53 q.pop(); 54 int tx,ty; 55 tx=t.loc/3; 56 ty=t.loc%3; 57 for(int i=0; i<4; i++) 58 { 59 int xx,yy; 60 xx=tx+dir[i][0]; 61 yy=ty+dir[i][1]; 62 if(xx>=3||xx<0||yy>=3||yy<0) 63 continue; 64 node temp; 65 char u; 66 u=t.s[xx*3+yy]; 67 strcpy(temp.s,t.s); 68 temp.s[xx*3+yy]='0'; 69 temp.s[tx*3+ty]=u; 70 temp.num=gethash(temp.s,l); 71 if(vis[temp.num]==true) 72 continue; 73 temp.loc=xx*3+yy; 74 temp.step=t.step+1; 75 if(strcmp(temp.s,s2)==0) 76 return temp.step; 77 vis[temp.num]=true; 78 q.push(temp); 79 } 80 } 81 return -1; 82 } 83 84 85 int main() 86 { 87 int start,loc; 88 get(); 89 while(scanf("%s%s",s1,s2)!=EOF) 90 { 91 //printf("s %s %s\n",s1,s2); 92 int len; 93 len=strlen(s1); 94 for(int i=0; i<len; i++) 95 if(s1[i]=='.') 96 { 97 s1[i]='0'; 98 loc=i; 99 break; 100 } 101 memset(vis,false,sizeof(vis)); 102 103 node t; 104 t.step=0; 105 t.loc=loc; 106 t.num=gethash(s1,l);//printf("ok"); 107 strcpy(t.s,s1); // 得到初始位置 108 //printf("t s %s\n",t.s); 109 vis[t.num]=true; 110 111 for(int i=0; i<len; i++) 112 if(s2[i]=='.') 113 { 114 s2[i]='0'; 115 break; 116 } 117 118 printf("%d\n",bfs(t)); 119 } 120 return 0; 121 }