[Ybtoj high-efficiency advanced 1.5] [Wide Search] Three-dimensional pile of boxes

[Ybtoj high-efficiency advanced 1.5] [Wide Search] Three-dimensional pile of boxes

topic

Insert picture description here
Insert picture description here


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;
}

Guess you like

Origin blog.csdn.net/qq_45621109/article/details/112389679