1581: 题目名称:九宫重排
题目描述
问题描述
如下面第一个图的九宫格中,放着 1~8 的数字卡片,还有一个格子空着。与空格子相邻的格子中的卡片可以移动到空格中。经过若干次移动,可以形成第二个图所示的局面。
我们把第一个图的局面记为:12345678.
把第二个图的局面记为:123.46758
显然是按从上到下,从左到右的顺序记录数字,空格记为句点。
本题目的任务是已知九宫的初态和终态,求最少经过多少步的移动可以到达。如果无论多少步都无法到达,则输出-1。
如下面第一个图的九宫格中,放着 1~8 的数字卡片,还有一个格子空着。与空格子相邻的格子中的卡片可以移动到空格中。经过若干次移动,可以形成第二个图所示的局面。
我们把第一个图的局面记为:12345678.
把第二个图的局面记为:123.46758
显然是按从上到下,从左到右的顺序记录数字,空格记为句点。
本题目的任务是已知九宫的初态和终态,求最少经过多少步的移动可以到达。如果无论多少步都无法到达,则输出-1。
输入
输入格式
输入第一行包含九宫的初态,第二行包含九宫的终态。
输入第一行包含九宫的初态,第二行包含九宫的终态。
输出
输出格式
输出最少的步数,如果不存在方案,则输出-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 ",ans); 59 return 0; 60 } 61 /* 62 63 12345678. 64 123.46758 65 66 3 67 68 */