康托展开:
康托展开表示的是当前n个元素排列在n个不同元素的全排列中的名次。
比如213在这3个数所有排列中排第3。
那么,对于n个数的排列,康托展开为:
ans=an*(n-1)!+an-1*(n-2)!+…+ai*(i-1)!+…+a2*1!+a1*0!
其中:a从右向左排号 2是a3, 1是a2, 3是a1
a表示每一个数的右边比它小的数的个数
2: 13 1<2 a3=1
1: 3 a2=0
3: a1=0
#include <map>
#include <set>
#include <queue>
#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
struct Matrix{
int m[4][4], step;
}sta;
int dx[3]={0,1}, dy[3]={1,0};
int f[10]={0,40320,5040,720,120,24,6,2,1};
int vis[500005];
set<int> ans;
int Contor( Matrix s ){
int ans=0;
for ( int i=1; i<=9; i++ ){
int tmp=0;
for ( int j=i+1; j<=9; j++ )
if( s.m[((i-1)/3)+1][((i-1)%3)+1] > s.m[((j-1)/3)+1][((j-1)%3)+1] ) tmp++;
ans+=tmp*f[i];
}
return ans;
}
void bfs(){
queue<Matrix> Q;
memset(vis,0,sizeof(vis));
vis[Contor(sta)]=1;
sta.step=0;
Q.push(sta);
while( !Q.empty() ){
Matrix u=Q.front();
Q.pop();
if( ans.count(Contor(u)) ){
printf("%d\n", u.step );
return ;
}
for ( int i=1; i<=3; i++ ){
for ( int j=1; j<=3; j++ ){
for ( int k=0; k<=1; k++ ){
int i0=i+dx[k];
int j0=j+dy[k];
if( i0<=3 && j0<=3 ){
Matrix u1=u;
swap( u1.m[i][j], u1.m[i0][j0] );
int ct=Contor(u1);
u1.step++;
if( vis[ct] ) continue;
vis[ct]=1;
Q.push(u1);
}
}
}
}
}
puts("-1");
}
int main(){
ans.clear();
ans.insert(69074); ans.insert(77576); ans.insert(135289); ans.insert(157120);
ans.insert(205759); ans.insert(227590); ans.insert(285303); ans.insert(293805);
while( scanf("%d%d%d", &sta.m[1][1], &sta.m[1][2], &sta.m[1][3])==3 ){
for ( int i=2; i<=3; i++ )
for ( int j=1; j<=3; j++ )
scanf("%d", &sta.m[i][j] );
bfs();
}
return 0;
}