描述
八方块移动游戏要求从一个含 8 个数字(用 1-8 表示)的方块以及一个空格方块(用 0 表示)的 3 × 3 矩阵的起始状态开始,不断移动该空格方块以使其和相邻的方块互换,直至达到所定义的目标状态。空格方块在中间位置时有上、下、左、右 4 个方向可移动,在四个角落上有 2个方向可移动,在其他位置上有 3 个方向可移动。例如,假设一个 3× 3 矩阵的初始状态为:
8 0 3 2 1 4 7 6 5 目标状态为: 1 2 3 8 0 4 7 6 5 则一个合法的移动路径为: 8 0 3 > 8 1 3 > 8 1 3 > 0 1 3 > 1 0 3 > 1 2 3 2 1 4 > 2 0 4 > 0 2 4 > 8 2 4 > 8 2 4 > 8 0 4 7 6 5 > 7 6 5 > 7 6 5 > 7 6 5 > 7 6 5 > 7 6 5
另外,在所有可能的从初始状态到目标状态的移动路径中,步数最少的路径被称为最短路径;在上面的例子中,最短路径为 5 。如果不存在从初试状态到目标状态的任何路径,则称该组状态无解。
问题
请设计有效的(细节请见评分规则)算法找到从八方块的某初试状态到某目标状态的所有可能路径中的最短路径。
输入
程序需读入初始状态和目标状态,这两个状态都由 9 个数字组成( 0 表示空格, 1-8 表示 8个数字方块),每行 3 个数字,数字之间用空格隔开。
输出
如果输入数据有解,输出一个表示最短路径的非负的整数;如果输入数据无解,输出 -1 。
输入样例1
8 0 3 2 1 4 7 6 5 1 2 3 8 0 4 7 6 5
输出样例1
5
解题思路
这道题我把图存成字符串,再用map映射步数,还用了九维数组打标记(笑哭)。剩下的就还是搜索下去。
题解
1 #include<bits/stdc++.h> 2 #define for(i,a,b) for(int i=a;i<=b;i++)//宏定义,很好用 3 using namespace std; 4 string x,y; 5 bool mp[9][9][9][9][9][9][9][9][9];// 6 map<string,int> sj;//map映射标记 7 queue<string> q;//队列,BFS标配 8 int dir[9][4]={-1,-1,3,1, -1,0,4,2, -1,1,5,-1, 0,-1,6,4, 1,3,7,5, 2,4,8,-1, 3,-1,-1,7, 4,6,-1,8, 5,7,-1,-1};//九个点上下左右分别的下标(-1代表越界) 9 void bfs(string a) 10 { 11 sj[a]=1;// 12 q.push(a); 13 while(!q.empty()) 14 { 15 int b; 16 a=q.front(); 17 q.pop(); 18 if(a==y){cout<<sj[a]-1;return;}//因为初始状态为1,所以要减一 19 for(i,0,a.size()-1) 20 { 21 if(a[i]==‘0‘)b=i;//记0的位置 22 } 23 for(i,0,3) 24 { 25 string aa=a; 26 if(dir[b][i]==-1)continue;//下标无效 27 swap(aa[b],aa[dir[b][i]]);//交换 28 if(sj[aa]==0) 29 { 30 sj[aa]=sj[a]+1;//步数加一 31 q.push(aa);//入队列 32 } 33 } 34 } 35 cout<<-1;//不行就输出-1 36 } 37 int main() 38 { 39 for(i,1,3) 40 for(j,1,3) 41 { 42 char a; 43 cin>>a; 44 x+=a; //字符串存储 45 } 46 for(i,1,3) 47 for(j,1,3) 48 { 49 char a; 50 cin>>a; 51 y+=a; //字符串存储 52 } 53 bfs(x);//开始搜索 54 return 0; 55 }
原文地址:https://www.cnblogs.com/hualian/p/11153083.html
时间: 2024-10-25 16:29:36