八数码问题
//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 *q) { int res=0; for(int i=1;i<10;i++) { int tp=0; for(int j=i+1;j<10;j++) if(q[j]<q[i]) tp++; res+=tp*p[9-i]; } return res+1; } void get_b(int x) { int tp[10],vis[10]; x--; memset(vis,0,sizeof(vis)); memset(tp,0,sizeof(tp)); for(int i=1;i<9;i++) { tp[i]=x/p[9-i]; x-=tp[i]*p[9-i]; } for(int i=1;i<10;i++) { int t=tp[i]+1; for(int j=1;j<10;j++) if(!vis[j]&&((--t)==0)) { b[i]=j; vis[j]=1; break; } } return; } 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]=0; 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; }