这题应该是广搜+康拓展开+模拟,可以用康拓展开,为什么还要用hash呢,毕竟hash不太严谨。
#include<bits/stdc++.h>
using namespace std;
string str="";
void input(){
for(int i=0;i<3;i++){
for(int j=0;j<3;j++){
int t;
scanf("%d",&t);
str+=char(t+48);
}
}
}
struct node{
string str,go;
};
queue<node> q;
int a[3][3],b[3][3],d[][2]={{0,0},{0,1},{0,2},{1,2},{2,2},{2,1},{2,0},{1,0}};
void put(string now){
int s=0;
for(int i=0;i<3;i++){
for(int j=0;j<3;j++) a[i][j]=now[s++];
}
}
void f1(){
int t=b[1][0];
for(int i=7;i>=1;i--) b[d[i][0]][d[i][1]]=b[d[i-1][0]][d[i-1][1]];
b[0][0]=t;
}
void f2(){
int t=b[1][2];
b[1][2]=b[1][1];
b[1][1]=b[1][0];
b[1][0]=t;
}
string z(){
string str="";
for(int i=0;i<3;i++){
for(int j=0;j<3;j++) str+=char(b[i][j]);
}
return str;
}
void print(){
int s=0;
for(int i=0;i<3;i++){
for(int j=0;j<3;j++){
putchar(b[i][j]);
putchar(32);
}
putchar(10);
}
putchar(10);
}
int pro[]={1,1,2,6,24,120,720,5040,40320,362880};
bool vis[362881];
bool Cantor(string str){
int s=0;
for(int i=0;i<9;i++){
int cnt=0;
for(int j=i+1;j<9;j++){
if(str[i]>str[j]) cnt++;
}
s+=cnt*pro[9-i-1];
}
if(!vis[s]){
vis[s]=1;
return 1;
}else return 0;
}
int main(){
input();
q.push({str,""});
Cantor(str);
while(!q.empty()){
node now=q.front();
if(now.str=="012345678"){
int len=now.go.length();
printf("%d\n",len);
put(str);
memcpy(b,a,sizeof(b));
print();
for(int i=0;i<len;i++){
if(now.go[i]) f2();
else f1();
print();
}
return 0;
}
put(now.str);
memcpy(b,a,sizeof(b));
f1();
string ss=z();
if(Cantor(ss)) q.push({ss,now.go+char(0)});
memcpy(b,a,sizeof(b));
f2();
ss=z();
if(Cantor(ss)) q.push({ss,now.go+char(1)});
q.pop();
}
return 0;
}