题目:http://lx.lanqiao.cn/problem.page?gpid=T42
分析:这一题可以对应到“迷宫最短路径”问题,是否能到达终点,若能到达最短步数是多少?用bfs,广度搜索解决,用到队列
将‘.’作为移动的对象,每移动一次,map[][](九宫格图案)状态改变一次,并且把每一次状态(一定要是新的状态)(定义为结构体node,结构体内容包括:map[][],从最初状态到当前状态移动的步数,‘.’的位置)存入队列que中,每一个map[][]对应一个数值val(将‘.’看做9,从左到右,从上到下抄写)
如:1 2 3
4 6
7 5 8 对应的val值为123946758,这个值用来判断当前map[][]是否出现过(判重,出现过就不计入que,相当于不走这一步了,不走已经走过的情况,不免死循环),每一个不一样的值放入set集合容器中(set可以快速的查询,删除,插入)
不断取que里队首元素作为移动的起点,新的状态放入队尾,直到队列为空,最终得出的步数即为最短步数。
代码:
1 #include<stdio.h> 2 #include<string.h> 3 #include<set> 4 #include<queue> 5 using namespace std; 6 int Gval;//目标图案对应的值 7 int D[4][2]= {-1,0,1,0,0,-1,0,1}; //上下左右 8 struct node 9 { 10 int x,y;//‘.’坐标 11 int step; 12 char map[3][3]; 13 }; 14 queue<node> que; 15 set<int> se; 16 int Get_value(char map[][3]) //得到九宫格图案对应的值 17 { 18 int val=0; 19 for(int i=0; i<3; i++) 20 { 21 for(int j=0; j<3; j++) 22 { 23 if(map[i][j]!='.') 24 { 25 val=val*10+map[i][j]-'0';//用来字符数字转换成整形数字 26 } 27 else 28 { 29 val=val*10+9; 30 } 31 } 32 } 33 return val; 34 } 35 int bfs() 36 { 37 node n,n1; 38 char Nmap[3][3]; 39 int i,j,xx,yy,val; 40 //如果队列为空,没找到,返回-1 41 if(que.empty()) 42 { 43 return -1; 44 } 45 while(!que.empty()) 46 { 47 n=que.front();//取出队首 48 que.pop(); 49 for( i=0; i<4; i++) 50 { 51 xx=n.x+D[i][0]; 52 yy=n.y+D[i][1]; 53 if(xx<0||xx>2||yy<0||yy>2) //越界 54 { 55 continue; 56 } 57 //走动了,形成新的图案,查看是否和以前的重了,如果没重,入队列 58 memcpy(Nmap,n.map,sizeof(n.map)); 59 Nmap[n.x][n.y]=n.map[xx][yy]; 60 Nmap[xx][yy]='.';//新的map 61 val=Get_value(Nmap); 62 if(val==Gval) //说明到达了目标状态 63 { 64 return n.step+1; 65 } 66 if(se.find(val)==se.end()) //说明set里没有此val,说明与之前的不重复 67 { 68 se.insert(val);//插入val 69 n1.x=xx; 70 n1.y=yy; 71 n1.step=n.step+1; 72 memcpy(n1.map,Nmap,sizeof(Nmap)); 73 que.push(n1); 74 } 75 } 76 } 77 } 78 int main() 79 { 80 node n; 81 char str1[15],str2[15],Smap[3][3],Gmap[3][3],ans; 82 int len=0,i,j,xx,yy; 83 //读入开始状态,并处理 84 gets(str1); 85 for(i=0; i<3; i++) 86 { 87 for(j=0; j<3; j++) 88 { 89 if(str1[len]=='.') 90 { 91 xx=i; 92 yy=j; 93 } 94 Smap[i][j]=str1[len]; 95 len++; 96 } 97 } 98 n.x=xx; 99 n.y=yy; 100 n.step=0; 101 memcpy(n.map,Smap,sizeof(Smap));//二维数组复制 102 que.push(n); 103 se.insert(Get_value(Smap)); 104 //读入目标状态,并处理 105 gets(str2); 106 len=0; 107 for(i=0; i<3; i++) 108 { 109 for(j=0; j<3; j++) 110 { 111 Gmap[i][j]=str2[len++]; 112 } 113 } 114 Gval=Get_value(Gmap);//目标状态对应的值 115 ans=bfs(); 116 printf("%d",ans); 117 return 0; 118 }