1.本题是一个基本的BFS模板,主要内容在于如何状态判重,我这里采用的是康托展开。
2.至于暴搜的状态我这里才、采用的是一个8位数,然后用数位分割转换状态。
康托展开:
long long bas[10]={1,1,2,6,24,120,720,5040,40320,362880}//阶乘 int Cantor_expansion(long long x) { long long wei[10]; for(int i=1;i<=9;i++) wei[i]=x/a[9-i]%10; int ans=0; for(int i=1;i<=9;i++) { int tmp=0; for(int j=i+1;j<=9;j++) if(wei[j]<wei[i]) tmp++; ans+=tmp*bas[9-i]; } return ans; }
四个操作:
void up() { int xx=q.front().p; if(xx-3<1) return; long long x=q.front().n; int wei=x/a[9-(xx-3)]%10; x=x-wei*a[9-(xx-3)]+wei*a[9-xx]; int tmp=Cantor_expansion(x); if(!visit[tmp]) { visit[tmp]=1; tonod c; c.p=xx-3; c.n=x; c.step=q.front().step+1; q.push(c); if(x==m) { step=c.step; bo=1; } } } void down() { int xx=q.front().p; if(xx+3>9) return; long long x=q.front().n; int wei=x/a[9-(xx+3)]%10; x=x-wei*a[9-(xx+3)]+wei*a[9-xx]; int tmp=Cantor_expansion(x); if(!visit[tmp]) { visit[tmp]=1; tonod c; c.p=xx+3; c.n=x; c.step=q.front().step+1; q.push(c); if(x==m) { step=c.step; bo=1; } } } void left() { int xx=q.front().p; if(xx==1||xx==4||xx==7) return; long long x=q.front().n; int wei=x/a[9-(xx-1)]%10; x=x-wei*a[9-(xx-1)]+wei*a[9-xx]; int tmp=Cantor_expansion(x); if(!visit[tmp]) { visit[tmp]=1; tonod c; c.p=xx-1; c.n=x; c.step=q.front().step+1; q.push(c); if(x==m) { step=c.step; bo=1; } } } void right() { int xx=q.front().p; if(xx==3||xx==6||xx==9) return; long long x=q.front().n; int wei=x/a[9-(xx+1)]%10; x=x-wei*a[9-(xx+1)]+wei*a[9-xx]; int tmp=Cantor_expansion(x); if(!visit[tmp]) { visit[tmp]=1; tonod c; c.p=xx+1; c.n=x; c.step=q.front().step+1; q.push(c); if(x==m) { step=c.step; bo=1; } } }
标程:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<queue> #include<cstdio> #include<cstring> #include<iostream> using namespace std; long long bas[10]={1,1,2,6,24,120,720,5040,40320,362880},a[9]={1,10,100,1000,10000,100000,1000000,10000000,100000000}; struct tonod{ long long n; int p,step; }; queue<tonod> q; bool visit[10000000],bo=0; long long m=123804765; int step=0; int Cantor_expansion(long long x) { long long wei[10]; for(int i=1;i<=9;i++) wei[i]=x/a[9-i]%10; int ans=0; for(int i=1;i<=9;i++) { int tmp=0; for(int j=i+1;j<=9;j++) if(wei[j]<wei[i]) tmp++; ans+=tmp*bas[9-i]; } return ans; } void up() { int xx=q.front().p; if(xx-3<1) return; long long x=q.front().n; int wei=x/a[9-(xx-3)]%10; x=x-wei*a[9-(xx-3)]+wei*a[9-xx]; int tmp=Cantor_expansion(x); if(!visit[tmp]) { visit[tmp]=1; tonod c; c.p=xx-3; c.n=x; c.step=q.front().step+1; q.push(c); if(x==m) { step=c.step; bo=1; } } } void down() { int xx=q.front().p; if(xx+3>9) return; long long x=q.front().n; int wei=x/a[9-(xx+3)]%10; x=x-wei*a[9-(xx+3)]+wei*a[9-xx]; int tmp=Cantor_expansion(x); if(!visit[tmp]) { visit[tmp]=1; tonod c; c.p=xx+3; c.n=x; c.step=q.front().step+1; q.push(c); if(x==m) { step=c.step; bo=1; } } } void left() { int xx=q.front().p; if(xx==1||xx==4||xx==7) return; long long x=q.front().n; int wei=x/a[9-(xx-1)]%10; x=x-wei*a[9-(xx-1)]+wei*a[9-xx]; int tmp=Cantor_expansion(x); if(!visit[tmp]) { visit[tmp]=1; tonod c; c.p=xx-1; c.n=x; c.step=q.front().step+1; q.push(c); if(x==m) { step=c.step; bo=1; } } } void right() { int xx=q.front().p; if(xx==3||xx==6||xx==9) return; long long x=q.front().n; int wei=x/a[9-(xx+1)]%10; x=x-wei*a[9-(xx+1)]+wei*a[9-xx]; int tmp=Cantor_expansion(x); if(!visit[tmp]) { visit[tmp]=1; tonod c; c.p=xx+1; c.n=x; c.step=q.front().step+1; q.push(c); if(x==m) { step=c.step; bo=1; } } } int main() { long long n; cin>>n; if(n==m) { printf("0"); return 0; } int wei[10],xx=9; for(int i=1;i<=9;i++) { wei[i]=n/a[9-i]%10; if(wei[i]==0) { xx=i; break; } } tonod c; c.n=n; c.p=xx; c.step=0; q.push(c); visit[Cantor_expansion(n)]; while(!q.empty()) { up(); down(); left(); right(); if(bo) { printf("%d",step); return 0; } q.pop(); } }