题意:经典的八数码问题,不废话了。
思路:BFS。搜索本身不难,难在判断节点有没有搜索过。其实这题在我刚开始搞ACM的时候用康托展开+A*这种高大上的算法刷过,这回纯粹是为了练习hash才刷的。所以写了个哈希,需要解决冲突,联想起当年上的数据结构课,这就是链表的头接法啊。
#include <iostream>
#include <stdio.h>
#include <cmath>
#include <algorithm>
#include <iomanip>
#include <cstdlib>
#include <string>
#include <memory.h>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <ctype.h>
#define INF 1000000010
#define ll long long
#define max3(a,b,c) max(a,max(b,c))
#define MAXN 1000
using namespace std;
//int start[9];
int state[1000000][9];
int head[1000003];
int next[1000000];
int pre[1000000];
char path[1000000];
int hash(int* s){
int re=0;
for(int i=0;i<9;i++){
re*=10;
re+=s[i];
}
return re%1000003;
}
bool insert(int s){
int h=hash(state[s]);
int tmp=head[h];
while(tmp!=-1){
if( memcmp(state+s,state+tmp,9*sizeof(int))==0 ){
return 0;
}
tmp=next[tmp];
}
next[s]=head[h];
head[h]=s;
return 1;
}
void print(int x){
if(pre[x]==-1){
return;
}
print(pre[x]);
cout<<path[x]<<" ";
}
int main(){
memset(next,-1,sizeof(next));
memset(head,-1,sizeof(head));
memset(pre,-1,sizeof(pre));
for(int i=0;i<9;i++){
char ch;
cin>>ch;
if(ch=='x') state[0][i]=9;
else state[0][i]=ch-'0';
}
insert(0);
int rear=1;
//bfs
int end;
bool ok=false;
queue<int> que; que.push(0);
while(!que.empty()){
int cur=que.front(); que.pop();
bool test=true;
for(int i=0;i<9;i++){
if(state[cur][i]!=i+1)test=false;
}
if(test){
ok=true;
end=cur;
break;
}
int k;
for(int i=0;i<9;i++){
if(state[cur][i]==9)k=i;
}
if(k>2){
memcpy(state+rear,state+cur,9*sizeof(int));
swap(state[rear][k],state[rear][k-3]);
if(insert(rear)){
que.push(rear);
pre[rear]=cur;
path[rear]='u';
rear++;
}
}
if(k<6){
memcpy(state+rear,state+cur,9*sizeof(int));
swap(state[rear][k],state[rear][k+3]);
if(insert(rear)){
que.push(rear);
pre[rear]=cur;
path[rear]='d';
rear++;
}
}
if(k%3!=0){
memcpy(state+rear,state+cur,9*sizeof(int));
swap(state[rear][k],state[rear][k-1]);
if(insert(rear)){
que.push(rear);
pre[rear]=cur;
path[rear]='l';
rear++;
}
}
if(k%3!=2){
memcpy(state+rear,state+cur,9*sizeof(int));
swap(state[rear][k],state[rear][k+1]);
if(insert(rear)){
que.push(rear);
pre[rear]=cur;
path[rear]='r';
rear++;
}
}
}
if(ok){
print(end);
cout<<endl;
}else{
cout<<"unsolvable"<<endl;
}
return 0;
}