如果觉得对你有帮助,能否点个赞或关个注,以示鼓励笔者呢?!博客目录 | 先点这里
题目链接:传送门(点我)
分析:以每一种状态作为节点进行搜索。
struct status{
int x,y,step; //x,y为当前空白格的坐标,step为空白格走的步数
char mp[5][5]; //存储当前状态地图
}
空白格移动一次,则是一种新的状态,层数表示移动的步骤数,一旦搜索到目标状态,就停止搜索返回层数,即是最少的步骤数。
AC代码
#include<bits/stdc++.h>
using namespace std;
int xx[4]={1,-1,0,0},yy[4]={0,0,1,-1},ans=-1;
string tar;//target status
struct status{
int x,y,step;
char mp[5][5];
}st;//start end
queue<status>q;
set<string>se;//judge the repeat
string calc_status(char t[][5])//calc current status and tostring
{
string s="";
for(int i=1;i<=3;i++)
for(int j=1;j<=3;j++)
s+=t[i][j];
return s;
}
int main()
{
for(int i=1;i<=3;i++){//init start
for(int j=1;j<=3;j++){
cin>>st.mp[i][j];
if(st.mp[i][j]=='.')st.x=i,st.y=j,st.step=0;
}
}
cin>>tar;
q.push(st);//start
se.insert(calc_status(st.mp));
while(q.size()!=0){ //BFS
status t = q.front();
q.pop();
if(calc_status(t.mp)==tar){ans=t.step;break;}
for(int i=0;i<4;i++){
status z;
z.x=t.x+xx[i];z.y=t.y+yy[i];z.step=t.step+1;
if(z.x<1||z.x>3||z.y<1||z.y>3)continue;//border
memcpy(z.mp,t.mp,sizeof(t.mp));
swap(z.mp[z.x][z.y],z.mp[t.x][t.y]);
string now_status = calc_status(z.mp);
if(se.count(now_status)!=0)continue;//judge repeat
se.insert(now_status);
q.push(z);
}
}
return cout<<ans<<endl,0;
}
tips:写传参的时候用到了二维数组,一时间竟有点糊涂,突然想起来C和Java的数组实现方式有一些区别,因为C的最后一维是不可缺的。
对于数组 int p[m][n];
如果要取p[i][j]的值(i>=0 && i<m && 0<=j && j < n),编译器是这样寻址的,它的地址为:p + i*n + j;