法一:广搜 + stl 实现
#include<stdio.h>
#include<set>
#include<iostream>
#include<string.h>
using namespace std;
typedef int State[9];
const int MAXSTATE = 1000000;
State st[MAXSTATE], goal ;
int dist[MAXSTATE];
set<int>vis;
void init_lookup_table(){ vis.clear();}
int try_to_insert(int s){
int v=0;
for(int i = 0 ;i < 9 ; i ++ )v = v*10 + st[s][i];
if(vis.count(v))return 0;
vis.insert(v);
return 1;
}
const int dx[] = {-1,1,0,0};
const int dy[] = {0,0,-1,1};
int bfs()
{
init_lookup_table();
int front = 1 , rear = 2 ;
while(front<rear)
{
State& s = st[front];
if(memcmp(goal,s,sizeof(s))==0)return front ;
int z ;
for(z = 0 ; z < 9 ; z++)if(!s[z])break;
int x = z / 3 ,y = z%3;
for(int i = 0 ; i< 4 ;i++)
{
int newx = x + dx[i];
int newy = y + dy[i];
int newz = newx*3+newy;
if(newx<3 && newy<3 && newx>=0 && newy>=0)
{
State& t = st[rear];
memcpy(&t,&s,sizeof(s));
t[z] = s[newz] ;
t[newz] = s[z];
dist[rear] = dist[front]+1;
if(try_to_insert(rear))rear++;
}
}
front++;
}
return 0;
}
int main()
{
for(int i = 0 ; i<9 ; i++ )cin>>st[1][i];
for(int i = 0 ; i<9 ; i++ )cin>>goal[i];
int ans = bfs();
if(ans>0)cout<<dist[ans]<<endl;
else cout<<"-1"<<endl;
return 0;
}
法二:bfs + 编码解码(康托展开)
int vis[36288],fact[9] ;
void init_lookup_table()
{
fact[0]=1;
for(int i = 0 ; i < 9 ; i++)fact[i] = fact[i-1]*i;
}
int try_to_insert(int s)
{
int code = 0;
for(int i = 0 ; i < 9 ; i++)
{
int cnt = 0;
for(int j = 0 ; j < 9 ; j++)if(st[s][j]<st[s][i])cnt++;
code+=fact[8-i]*cnt;
}
if(vis[code])return 0;
return vis[code] = 1;
}
法三:bfs + 哈希
法四:双向bfs
法五:A*
法六:IDA*