[Ybtoj high-efficiency advanced 1.5] [Wide Search] Three-dimensional pile of boxes
topic
Problem-solving ideas
Record the three positions of the rectangular parallelepiped
and only record itself when standing upright, record the bottom vertically, and record the right side horizontally.
Push up, down, left and right in these three situations. What kind of state are you pushing up, down, left and right?
Classic wide search
Code
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
struct lzf{
int x,y,t,b;
}q[1000100];
char c;
int n,m,h,t,zx,zy,a[520][520],p[520][520][4];
int fx[4][5]={
{
},{
0,-1,0,2,0},{
0,-2,0,1,0},{
0,-1,0,1,0}};
int fy[4][5]={
{
},{
0,0,2,0,-1},{
0,0,1,0,-1},{
0,0,1,0,-2}}; //坐标的变化
int ft[4][5]={
{
},{
0,2,3,2,3},{
0,1,2,1,2},{
0,3,1,3,1}}; //状态的变化
bool check(int xx,int yy,int tt)
{
if (xx<1||xx>n||yy<1||yy>m) return 0;
if (tt==1&&a[xx][yy]==0) return 1; //只有一个立着,不可以在易碎面上
if (tt==2&&a[xx][yy]!=1&&a[xx-1][yy]!=1&&xx-1>0) return 1; //竖着,两个都不能是禁地
if (tt==3&&a[xx][yy]!=1&&a[xx][yy-1]!=1&&yy-1>0) return 1; //横着,两个也不能是禁地
return 0;
}
bool dfs()
{
do{
h++;
for (int i=1;i<=4;i++)
{
int xx=q[h].x+fx[q[h].t][i],yy=q[h].y+fy[q[h].t][i],tt=ft[q[h].t][i];
if (check(xx,yy,tt)&&!p[xx][yy][tt]) //可以走,且没走过
{
q[++t].x=xx;
q[t].y=yy;
q[t].t=tt;
q[t].b=q[h].b+1;
p[xx][yy][tt]=1; //进队
if (xx==zx&&yy==zy&&q[t].t==1)
{
printf("%d\n",q[t].b);
return 0;
}
}
}
} while (h<t);
return 1;
}
int main()
{
while (1)
{
scanf("%d%d",&n,&m);
if (!n&&!m) break;
h=0,t=1;
int vis=0;
memset(a,0,sizeof(a));
memset(q,0,sizeof(q));
memset(p,0,sizeof(p));
q[t].t=1;
for (int i=1;i<=n;i++)
for (int j=1;j<=m;j++)
{
cin>>c;
if (c=='#') a[i][j]=1;
if (c=='E') a[i][j]=-1;
if (c=='O') zx=i,zy=j,a[i][j]=0;
if (c=='X')
{
if (vis)
if (q[t].x+1==i&&q[t].x)
q[t].t=2;
else q[t].t=3; //更改起始点的状态
q[t].x=i;
q[t].y=j;
vis=1;
} //预处理
}
p[q[t].x][q[t].y][q[t].t]=1;
if (dfs()) printf("Impossible\n");
}
return 0;
}