【搜索】九宫重排

1581: 题目名称:九宫重排

题目描述

问题描述
以下面第一个图的九宫格中,放着 1~8 的数字卡片,还有一个格子空着。与空格子相邻的格子中的卡片能够移动到空格中。通过若干次移动,能够造成第二个图所示的局面。
咱们把第一个图的局面记为:12345678.
把第二个图的局面记为:123.46758
显然是按从上到下,从左到右的顺序记录数字,空格记为句点。
本题目的任务是已知九宫的初态和终态,求最少通过多少步的移动能够到达。若是不管多少步都没法到达,则输出-1。
 

输入

输入格式
输入第一行包含九宫的初态,第二行包含九宫的终态。
 

输出

输出格式
输出最少的步数,若是不存在方案,则输出-1。
 

 

样例输入

12345678.
123.46758

样例输出

3

利用字符串进行标记,考察了,一位数组转二维,还有BFS搜索。
对行号进行整除,对列号进行取余。

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 typedef struct Node{
 4     string S;
 5     int step;
 6 }Node;
 7 int dir[4][2]={
 8         {-1,0},
 9     {0,-1},{0,1},
10         {1,0}
11 };
12 map< string , int >Mp;
13 string s,e,tmp;
14 int main()
15 {
16     ios_base :: sync_with_stdio(0);
17     cin.tie(NULL),cout.tie(NULL);
18     
19     cin>>s>>e;
20     queue<Node> Q;
21     Q.push(Node{s,0});
22     int x , y , ans = -1 ;
23     Mp[s] = 1;
24     while( !Q.empty() ){
25         Node cur = Q.front() ,Next ;
26         Q.pop();
27         s = cur.S;
28         if( s == e ){
29             ans = cur.step;
30             break;
31         }
32         for(int i=0;i<9;i++){
33             if( s[i] == '.' ){
34                 x = i/3 ;
35                 y = i%3 ;
36                 //cout<<s<<endl;
37                 //cout<<x<<" "<<y<<endl;
38                 break;
39             }
40         }
41         for(int i=0;i<4;i++){
42             int tx = x + dir[i][0];
43             int ty = y + dir[i][1];
44             if( 0<=tx && tx<=2 && 0<=ty && ty<=2 ){
45                 //cout << "Tx :" << tx << " " << ty <<endl;
46                 tmp = s;
47                 swap( tmp[x*3+y] , tmp[tx*3+ty] );
48                 //cout<<tmp<<endl;
49                 if( !Mp[tmp] ){
50                     Mp[tmp] = 1 ;
51                     Next.S = tmp;
52                     Next.step = cur.step+1;
53                     Q.push(Next);
54                 }
55             }
56         }
57     }
58     printf("%d\n",ans);
59     return 0;
60 }
61 /*
62 
63 12345678.
64 123.46758
65 
66 3
67 
68 */
View Code