洛谷 - P2578 - 九数码游戏 - bfs

时间:2023-03-09 15:01:49
洛谷 - P2578 - 九数码游戏 - bfs

https://www.luogu.org/problemnew/show/P2578

一个挺搞的东西,用康托展开做记忆化搜索可以少一个log的查询。

#include <bits/stdc++.h>
using namespace std;
#define ll long long static const int fac[] = {, , , , , , , , , ,}; // 阶乘 //康托展开
int cantor(int *a,int n)
{
int code=;
for(int i=; i<n; i++)
{
int x=;
int c=,m=;//c记录后面的阶乘
for(int j=i+; 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[]= {};
for(int i=; i<n; i++)
{
int r = code / fac[n-i-];
code %= fac[n-i-];
int cnt = ;
int j;
for(j=; j<=n; j++)
{
if(vis[j]==)
{
cnt++;
if(cnt==r+)
{
a[i]=j;
vis[j]=;
break;
}
}
}
} /*printf("decantor=");
for(int i=0; i<n; i++)
{
printf(" %d",a[i]);
}
printf("\n");*/
} ll rot1(ll code)
{
int a[];
decantor(code,a,);
int t=a[];
a[]=a[];
a[]=a[];
a[]=a[];
a[]=a[];
a[]=a[];
a[]=a[];
a[]=a[];
a[]=t;
int ans=cantor(a,);
return ans;
} int rot2(int code)
{
int a[];
decantor(code,a,);
int t=a[];
a[]=a[];
a[]=a[];
a[]=t;
int ans=cantor(a,);
return ans;
} struct dat
{
int cur;
int pre;
} d,dt,data[]; queue<dat> q; void print(int code)
{
int a[],n=; bool vis[]= {};
for(int i=; i<n; i++)
{
int r = code / fac[n-i-];
code %= fac[n-i-];
int cnt = ;
int j;
for(j=; j<=n; j++)
{
if(vis[j]==)
{
cnt++;
if(cnt==r+)
{
a[i]=j;
vis[j]=;
break;
}
}
}
} printf("\n");
for(int i=; i<n; i++)
{
printf("%d%c",a[i]-," \n"[i%==]);
}
} void show(dat d)
{
stack<ll> s;
s.push(d.cur);
while(d.pre!=-)
{
s.push(d.pre);
d=data[d.pre];
} printf("%d",s.size()-); 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=-; 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[];
for(int i=; i<; i++)
{
scanf("%d",&a[i]);
a[i]++;
} int s=cantor(a,);
bfs(s);
}