https://codeforces.com/gym/102460
目标就是让1的右端点移动到(3,6)的位置,从(3,6)出去还要两步,那么最多就是移动8步,又因为最多只有10个物品,而且我们可以用hash标记棋盘的某个状态是否出现过,那么每次尝试移动每个物品,bfs就行了,最坏情况是(10*2)^8的状态,但是由于互相碰撞的原因,实际情况会少很多状态,30ms就跑过了
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int mod1=1e9+7;
const int mod2=998244353;
const int bas=1e9;
int ans,tot;
int ini[8][8],tmp[8][8],a[8][8];
int dir[12],len[12],inix[12],iniy[12];
struct board
{
int a[8][8],val;
};
queue<board> q;
unordered_map<ll,bool> mp;
inline void prework()
{
for(int i=1;i<=6;i++)
for(int j=1;j<=6;j++)
scanf("%d",&ini[i][j]);
for(int i=0;i<=7;i++)
ini[i][0]=ini[i][7]=ini[0][i]=ini[7][i]=11;
}
inline ll geths(board & x)
{
ll t1=0,t2=0;
for(int i=1;i<=6;i++)
for(int j=1;j<=6;j++)
{
t1=(t1*11+x.a[i][j])%mod1;
t2=(t2*11+x.a[i][j])%mod2;
}
return t1*bas+t2;
}
inline void mainwork()
{
ans=-1;int x,y;
for(int i=1;i<=6;i++)
for(int j=1;j<=6;j++)
{
x=ini[i][j];tot=max(x,tot);
if(x>0 && len[x]==0)
{
inix[x]=i;iniy[x]=j;
if(j+1<=6 && ini[i][j+1]==x)
{
dir[x]=1;len[x]=2;
if(j+2<=6 && ini[i][j+2]==x)
len[x]++;
}
else
{
dir[x]=2;len[x]=2;
if(i+2<=6 && ini[i+2][j]==x)
len[x]++;
}
}
}
if(dir[1]==1 && len[1]==2 && inix[1]==3)
ans=0;
if(ans<0)
return;
board u,d;d.val=0;ll hs;
for(int i=0;i<=7;i++)
for(int j=0;j<=7;j++)
d.a[i][j]=ini[i][j];
hs=geths(d);
mp[hs]=true;q.push(d);
while(!q.empty())
{
u=q.front();q.pop();
for(int i=1;i<=tot;i++)
inix[i]=0,iniy[i]=0;
for(int i=0;i<=7;i++)
for(int j=0;j<=7;j++)
{
d.a[i][j]=u.a[i][j];
x=d.a[i][j];
if(!inix[x])
inix[x]=i,iniy[x]=j;
}
d.val=u.val+1;
for(int i=1;i<=tot;i++)
if(dir[i]==1)
{
x=inix[i];y=iniy[i];
if(u.a[x][y-1]==0)
{
for(int j=0;j<len[i];j++)
d.a[x][y-1+j]=u.a[x][y+j];
d.a[x][y+len[i]-1]=0;
if(d.a[3][6]==1){ans=d.val+2;return;}
hs=geths(d);
if(!mp[hs] && d.val<=7)
mp[hs]=true,q.push(d);
for(int j=y-1;j<=y+len[i]-1;j++)
d.a[x][j]=u.a[x][j];
}
if(u.a[x][y+len[i]]==0)
{
for(int j=0;j<len[i];j++)
d.a[x][y+1+j]=u.a[x][y+j];
d.a[x][y]=0;
if(d.a[3][6]==1){ans=d.val+2;return;}
hs=geths(d);
if(!mp[hs] && d.val<=7)
mp[hs]=true,q.push(d);
for(int j=y;j<=y+len[i];j++)
d.a[x][j]=u.a[x][j];
}
}
else
{
x=inix[i];y=iniy[i];
if(u.a[x-1][y]==0)
{
for(int j=0;j<len[i];j++)
d.a[x-1+j][y]=u.a[x+j][y];
d.a[x+len[i]-1][y]=0;
hs=geths(d);
if(!mp[hs] && d.val<=7)
mp[hs]=true,q.push(d);
for(int j=x-1;j<=x+len[i]-1;j++)
d.a[j][y]=u.a[j][y];
}
if(u.a[x+len[i]][y]==0)
{
for(int j=0;j<len[i];j++)
d.a[x+1+j][y]=u.a[x+j][y];
d.a[x][y]=0;
hs=geths(d);
if(!mp[hs] && d.val<=7)
mp[hs]=true,q.push(d);
for(int j=x;j<=x+len[i];j++)
d.a[j][y]=u.a[j][y];
}
}
}
if(ans==0 || ans>10)
ans=-1;
}
inline void print()
{
printf("%d\n",ans);
}
int main()
{
prework();
mainwork();
print();
return 0;
}