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;
}

八数码简单难题

posted @ 2025-07-09 17:42  liyuan2023  阅读(38)  评论(0)    收藏  举报