一个康托展开的板子
八数码问题传送门
//Achen
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<vector>
#include<queue>
#include<ctime>
#include<cmath>
const int N=107;
typedef long long LL;
using namespace std;
template<typename T> void read(T &x) {
char ch=getchar(); x=0; T f=1;
while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
if(ch=='-') f=-1,ch=getchar();
for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0'; x*=f;
}
int fac[N];
int kt(int n,int a[]) {
int k=0;
for(int i=1;i<=n;i++) {
int t=0;
for(int j=i+1;j<=n;j++)
if(a[j]<a[i]) t++;
k+=t*fac[n-i];
}
return k+1;
}
int vis[N];
void rkt(int n,int k,int a[]) {
memset(vis,0,sizeof(vis));
k--;
for(int i=1;i<=n;i++) {
int t=k/fac[n-i],j;
for(j=1;j<=n;j++) if(!vis[j]) {
if(!t) break;
t--;
}
a[i]=j; vis[j]=1;
k=k%fac[n-i];
}
}
int main() {
#ifdef DEBUG
freopen(".in","r",stdin);
freopen(".out","w",stdout);
#endif
return 0;
}
//Twenty
#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<ctime>
#include<queue>
#define INF 0xfffffff
using namespace std;
typedef long long LL;
const int maxn=362880+5;
int T,a[10],b[10],p[10],f[maxn],d[maxn],g[maxn];
void read(int &ret) {
int f=1; ret=0; char ch=getchar();
while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
if(ch=='-') f=-1,ch=getchar();
for(;ch>='0'&&ch<='9';ch=getchar()) ret=ret*10+ch-'0'; ret*=f;
}
struct node {
int x;
node(int x):x(x){}
friend bool operator <(const node &A,const node &B) {
return d[A.x]+g[A.x]>d[B.x]+g[B.x];
}
};
priority_queue<node>que;
int get_rk(int a[]) {
int k=0;
for(int i=1;i<=9;i++) {
int t=0;
for(int j=i+1;j<=9;j++)
if(a[j]<a[i]) t++;
k+=t*p[9-i];
}
return k+1;
}
int vis[10];
void get_b(int k) {
memset(vis,0,sizeof(vis));
k--;
for(int i=1;i<=9;i++) {
int t=k/p[9-i],j;
for(j=1;j<=9;j++) if(!vis[j]) {
if(!t) break;
t--;
}
b[i]=j; vis[j]=1;
k=k%p[9-i];
}
}
void cal(int x){
if(g[x]!=-1) return;
g[x]=0;
for(int i=1;i<10;i++) {
int tp=b[i];
int xx=(b[i]-1)/3,yy=b[i]-xx*3;xx++;
int o=(i-1)/3,p=i-o*3;
g[x]+=abs(xx-o-1)+abs(yy-p);
}
return;
}
void push(int *q,int pr) {
int x=get_rk(q);
if(d[pr]+1>=d[x]) return;
d[x]=min(d[x],d[pr]+1);
//if(g[x]!=-1) return;
cal(x);
que.push(node(x));
}
int op(int x,int y) {
return (x-1)*3+y;
}
void smg(int tpp,int tp,int pr) {
swap(b[tpp],b[tp]);
push(b,pr);
swap(b[tpp],b[tp]);
}
void work() {
int x=get_rk(a);
cal(x); d[x]=0;
while(!que.empty()) que.pop();
que.push(node(x));
int tp;
while(!que.empty()) {
node now=que.top();
que.pop();
if(now.x==1) break;
get_b(now.x);
for(int i=1;i<10;i++) if(b[i]==9) {
tp=i; break;
}
int xx=(tp-1)/3,yy=tp-xx*3; xx++;
if(xx>1) {
int tpp=op(xx-1,yy);
smg(tpp,tp,now.x);
}
if(xx<3) {
int tpp=op(xx+1,yy);
smg(tpp,tp,now.x);
}
if(yy>1) {
int tpp=op(xx,yy-1);
smg(tpp,tp,now.x);
}
if(yy<3) {
int tpp=op(xx,yy+1);
smg(tpp,tp,now.x);
}
}
}
void init() {
read(T);
p[0]=1; p[1]=1;
for(int i=2;i<10;i++) p[i]=p[i-1]*i;
while(T--) {
memset(g,-1,sizeof(g));
for(int i=1;i<maxn;i++) d[i]=INF;
for(int i=1;i<10;i++) {
read(a[i]);
if(a[i]==0) a[i]=9;
}
work();
if(d[1]!=INF) printf("%d\n",d[1]);
else printf("No Solution!\n");
}
}
int main()
{
init();
return 0;
}