【洛谷】P1379 八数码难题

【题目连接】https://www.luogu.com.cn/problem/P1379

【难度】普及+/提高−

【目标】A* 入门经典题,用各数字到目标位置的曼哈顿距离之和作为估价函数,配合优先队列搜索。

 

【暴力搜索】 用时8.09s  内存14.27MB

#include<cstdio>
#include<iostream>
#include<map> 
#include<queue> 
using namespace std;

string s;
string des="123804765";
map<string,int> ma;

int bfs(string s){
	ma[s] = 0;
	queue< string > que;
	que.push(s);
	while( !que.empty() ){
		string f = que.front();
		que.pop();
		if( f == des ){
			return ma[f] ;
		}
		int index = f.find('0');
		//朝上
		if( index/3>0 ){
			string tmp = f;
			swap( tmp[index-3],tmp[index] );
			if( !ma.count(tmp) ){
				que.push(tmp);
				ma[tmp] = ma[f] + 1;				
			}	
		} 
		//朝下 
		if( index/3<2 ){
			string tmp = f;
			swap( tmp[index+3],tmp[index] );
			if( !ma.count(tmp) ){
				que.push(tmp);
				ma[tmp] = ma[f] + 1;				
			}			
		} 
		//朝左 
		if( index%3>0 ){
			string tmp = f;
			swap( tmp[index-1],tmp[index] );
			if( !ma.count(tmp) ){
				que.push(tmp);
				ma[tmp] = ma[f] + 1;				
			}			
		} 
		//朝右 
		if( index%3<2 ){
			string tmp = f;
			swap( tmp[index+1],tmp[index] );
			if( !ma.count(tmp) ){
				que.push(tmp);
				ma[tmp] = ma[f] + 1;				
			}			
		} 
	}
}

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

  

【A*搜索】  用时436ms  内存5.76MB

#include<set>
#include<queue>
#include<iostream>
using namespace std;
 
string s,t = "123804765"; 

//将s转移到t的最少操作次数
int check(string s){
    int cnt = 0;
    for(int i=0;i<s.length();i++){
        if( s[i]!=t[i]) cnt++;
    }
    return cnt-1; 
}
 
 
struct node{
    string s;
    int g,h;
    //运算符重载
    bool operator>(const node &y) const{
        return g+h > y.g+y.h;
    }
};
 
//struct cmp{
//    bool operator()(const node & __x, const node & __y) const
//    { return __x.g + __x.h > __y.g + __y.h; }
//};
 
set<string> se;
int A_STAR(string s){
    priority_queue< node ,vector<node> ,greater<node> > q;
    q.push( (node){s,0,check( s )} );
    se.insert(s);
    while( q.size() ){
        node f = q.top();q.pop();
        if( f.s == t ){
            return f.g;
        }
        int index = f.s.find('0');
        int tx = index -3 ;
        if( tx>=0 ){
            string tmp = f.s;
            swap( tmp[index] , tmp[tx] );
            if( se.find( tmp ) == se.end()  ){
                se.insert(tmp);
                q.push( (node){ tmp,f.g+1,check( tmp ) } );
            }
        }
        tx = index + 3 ;
        if( tx<=8 ){
            string tmp = f.s;
            swap( tmp[index] , tmp[tx] );
            if( se.find( tmp ) == se.end()  ){
                se.insert(tmp);
                q.push( (node){ tmp,f.g+1,check( tmp ) } );
            }
        }  
        tx = index - 1 ;
        if( tx>=0 && index%3!=0 ){
            string tmp = f.s;
            swap( tmp[index] , tmp[tx] );
            if( se.find( tmp ) == se.end()  ){
                se.insert(tmp);
                q.push( (node){ tmp,f.g+1,check( tmp ) } );
            }
        }          
        tx = index + 1 ;
        if( tx<=8 && index%3!=2){
            string tmp = f.s;
            swap( tmp[index] , tmp[tx] );
            if( se.find( tmp ) == se.end()  ){
                se.insert(tmp);
                q.push( (node){ tmp,f.g+1,check( tmp ) } );
            }
        }               
    }
    return -1;
}
 
 
int main(){
    cin>>s;
    cout << A_STAR(s);
    return 0;
}

  

  

posted @ 2026-09-25 22:55  费先生  阅读(6)  评论(0)    收藏  举报