暴力枚举。不需要对数据进行预处理,直接平移。
两层循环枚举碎片,四层循环枚举两块碎片平移的距离【如第一块碎片左上角从(1,1)平移到(1+dx1,1+dy1)】,最后两层循环判断。
时间复杂度$O(N^{6}K^{2})$。
核心代码:
bool check(int p,int X,int Y)
{return X>0&&X<=n&&Y>0&&Y<=n&&(s[p][X][Y]=='#');}
for(int i=1;i<=k;++i)
for(int j=i+1;j<=k;++j)
for(int dx1=-n+1;dx1<=n-1;++dx1)
for(int dy1=-n+1;dy1<=n-1;++dy1)
for(int dx2=-n+1;dx2<=n-1;++dx2)
for(int dy2=-n+1;dy2<=n-1;++dy2)
{
bool ok=1,c1,c2;
for(int x=1;x<=n;++x)
for(int y=1;y<=n;++y)
{
c1=check(i,x+dx1,y+dy1);
c2=check(j,x+dx2,y+dy2);
if (c1&&c2) ok=0;
if ((s[0][x][y]=='#')!=(c1||c2)) ok=0;
}
if (ok) {printf("%d %d
",i,j);return 0;}
}
注意:用ok变量判断是否合法,不要乱跳循环。不必刻意判断$ exttt{#}$是否出界,只需判断:
1.两块碎片的$ exttt{#}$是否重合;
2.碎片拼合后与原雕像是否一致。