【洛谷】P1379 八数码难题

【题目链接】P1379 八数码难题 - 洛谷 (luogu.com.cn)

【普通bfs搜索】

#include <bits/stdc++.h>
using namespace std;
string s,t="123804765";

int dx[4] = {0,0,1,-1};
int dy[4] = {1,-1,0,0};

struct node{
	string s;
	int step; 
};
unordered_set<string> se;

int bfs(string s){
	queue<node> q;
	q.push( {s,0} );
	se.insert( s );
	while( q.size() ){
		auto [cur_s,cur_step] = q.front() ; q.pop() ;
		if( cur_s == t ){
			return cur_step;
		}
		int cur_index = cur_s.find('0') ;
		
		int cur_x = cur_index/3 , cur_y = cur_index%3;
		
		for(int i=0;i<4;i++){
			string next_s = cur_s;
			int tx = cur_x+dx[i] , ty = cur_y+dy[i];
			if( tx<0 || tx>2 || ty<0 || ty>2  ) continue;
			int next_index = tx*3+ty;
			swap( next_s[cur_index] , next_s[next_index] ) ;
			if( se.count( next_s ) ) continue;
			se.insert( next_s ) ;
			q.push( { next_s , cur_step+1 } );				
		}	
	}
	return -1;
}

int main(){
	cin>>s;
	cout << bfs(s);
	return 0;
}

  

【A*搜索】

#include <bits/stdc++.h>
using namespace std;
string s,t="123804765";

int dx[4] = {0,0,1,-1};
int dy[4] = {1,-1,0,0};
unordered_map<string,int> mp; //标记状态

struct node{
	string s;
	int g_step;//真实最少步数
	int h_step;//预估最少步数
	int f_step;//预估总步数 
	
	node(string _s , int _g , int _h ) : 
		s( _s ) , g_step( _g ) , h_step( _h ) , f_step( _g+_h ){}
	
	bool operator > (const node& other ) const{
		if( f_step!=other.f_step ) return f_step > other.f_step;
		return h_step > other.h_step ;
	} 
};

//预估函数 
int h( string s ){
	int cnt = 0;
	for( int i=0;i<(int)s.size();i++ ){
		if( s[i]!=t[i] )
			cnt++;
	}
	return cnt-1;
} 

int bfs(string s){
	if( s==t ) return 0;
	priority_queue<node,vector<node>, greater<node> > q;
	q.push( {s,0,h(s)} );
	mp[s] = 0;
	while( q.size() ){
		string cur_s = q.top().s ;
        int cur_step = q.top().g_step;
        q.pop() ;
		if( cur_s == t ){
			return cur_step;
		}
		int cur_index = cur_s.find('0') ;
		int cur_x = cur_index/3 , cur_y = cur_index%3;
		for(int i=0;i<4;i++){
			string next_s = cur_s;
			int tx = cur_x+dx[i] , ty = cur_y+dy[i];
			if( tx<0 || tx>2 || ty<0 || ty>2  ) continue;
			int next_index = tx*3+ty; //计算空格在字符串中交换元素的下标 
			swap( next_s[cur_index] , next_s[next_index] ) ;
			if( mp.count( next_s ) && mp[next_s] <= cur_step+1 ) continue;
			mp[next_s] =  cur_step+1 ; 
			q.push( { next_s , cur_step+1 , h( next_s ) } );				
		}	
	}
	return -1;
}

int main(){
	cin>>s;
	cout << bfs(s);
	return 0;
}

  

posted @ 2026-09-26 19:49  费先生  阅读(4)  评论(0)    收藏  举报