2025.7.6 BFS
2025.7.6 BFS
没啥好讲的,直接看例题。
例题P1379
题目描述
在 \(3×3\) 的棋盘上,摆有 \(8\) 个棋子,每个棋子上标有 1 至 8 的某一数字。棋盘中留有一个空格,空格用 \(0\) 来表示。空格周围的棋子可以移到空格中。要求解的问题是:给出一种初始布局和目标布局(为了使题目简单,设目标状态为 \(123804765\) ),找到一种最少步骤的移动方法,实现从初始布局到目标布局的转变。
思路
时间复杂度为 \(9\) 的全排列,即 \(O(9!)\) ,肯定不会超时。用字符串来维护每个格子的状态, \(BFS\) 搜索保证一定为最优解,用 \(map\) 记录状态不重复。
AC代码
#include<bits/stdc++.h>
using namespace std;
string s,ans="123804765";
int fx,fy,dx[4]={-1,0,0,1},dy[4]={0,-1,1,0};
char a[5][5];
map<string,bool> mp;
int id(int x,int y){
return (x-1)*3+y-1;//对应位置
}
struct node{
int x,y,step;//“0”点位置,步数
string s;//状态
};
queue<node> q;
int bfs(int fx,int fy,string s){
q.push({fx,fy,0,s});
while(!q.empty()){
node p=q.front();
q.pop();
if(p.s==ans){
return p.step;
}
for(int i=0;i<4;i++){
int xx=p.x+dx[i],yy=p.y+dy[i];
if(xx>=1&&xx<=3&&yy>=1&&yy<=3){
int t1=id(p.x,p.y),t2=id(xx,yy);
string t=p.s;
swap(t[t1],t[t2]);//现在的状态
if(!mp[t]){
mp[t]=1;
q.push({xx,yy,p.step+1,t});
}
}
}
}
}//样例保证有解
int main(){
cin>>s;
a[1][1]=s[0],a[1][2]=s[1],a[1][3]=s[2];
a[2][1]=s[3],a[2][2]=s[4],a[2][3]=s[5];
a[3][1]=s[6],a[3][2]=s[7],a[3][3]=s[8];
for(int i=1;i<=3;i++){
for(int j=1;j<=3;j++){
if(a[i][j]=='0'){
fx=i,fy=j;
}
}
}
cout<<bfs(fx,fy,s);
return 0;
}
八数码
简单难题

浙公网安备 33010602011771号