https://www.luogu.org/problemnew/show/P2578
一个挺搞的东西,用康托展开做记忆化搜索可以少一个log的查询。
#include <bits/stdc++.h> using namespace std; #define ll long long static const int fac[] = {1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880,3628800}; // 阶乘 //康托展开 int cantor(int *a,int n) { int code=0; for(int i=0; i<n; i++) { int x=0; int c=1,m=1;//c记录后面的阶乘 for(int j=i+1; j<n; j++) { if(a[j]<a[i])x++; m*=c; c++; } code+=x*m; } //printf("cantor=%d\n",code); return code; } //逆康托展开 void decantor(int code,int *a,int n) { bool vis[11]= {}; for(int i=0; i<n; i++) { int r = code / fac[n-i-1]; code %= fac[n-i-1]; int cnt = 0; int j; for(j=1; j<=n; j++) { if(vis[j]==0) { cnt++; if(cnt==r+1) { a[i]=j; vis[j]=1; break; } } } } /*printf("decantor="); for(int i=0; i<n; i++) { printf(" %d",a[i]); } printf("\n");*/ } ll rot1(ll code) { int a[9]; decantor(code,a,9); int t=a[0]; a[0]=a[3]; a[3]=a[6]; a[6]=a[7]; a[7]=a[8]; a[8]=a[5]; a[5]=a[2]; a[2]=a[1]; a[1]=t; int ans=cantor(a,9); return ans; } int rot2(int code) { int a[9]; decantor(code,a,9); int t=a[5]; a[5]=a[4]; a[4]=a[3]; a[3]=t; int ans=cantor(a,9); return ans; } struct dat { int cur; int pre; } d,dt,data[362880]; queue<dat> q; void print(int code) { int a[9],n=9; bool vis[11]= {}; for(int i=0; i<n; i++) { int r = code / fac[n-i-1]; code %= fac[n-i-1]; int cnt = 0; int j; for(j=1; j<=n; j++) { if(vis[j]==0) { cnt++; if(cnt==r+1) { a[i]=j; vis[j]=1; break; } } } } printf("\n"); for(int i=0; i<n; i++) { printf("%d%c",a[i]-1," \n"[i%3==2]); } } void show(dat d) { stack<ll> s; s.push(d.cur); while(d.pre!=-1) { s.push(d.pre); d=data[d.pre]; } printf("%d",s.size()-1); while(!s.empty()) { print(s.top()); s.pop(); } } inline bool found(int code){ return !code; } void bfs(int s) { //memset(data,0,sizeof(data)); d.cur=s; d.pre=-1; if(found(d.cur)) { show(d); return; } data[d.cur]=d; q.push(d); while(!q.empty()) { d=q.front(); q.pop(); int t1=rot1(d.cur); if(data[t1].cur) ; else { dt.cur=t1; dt.pre=d.cur; if(found(dt.cur)) { show(dt); return; } data[t1]=dt; q.push(dt); } int t2=rot2(d.cur); if(data[t2].cur) ; else { dt.cur=t2; dt.pre=d.cur; if(found(dt.cur)) { show(dt); return; } data[t2]=dt; q.push(dt); } } printf("UNSOLVABLE\n"); } int main() { int a[9]; for(int i=0; i<9; i++) { scanf("%d",&a[i]); a[i]++; } int s=cantor(a,9); bfs(s); }