题意:在r*c的矩形方格地图中,有钢地板和易碎地板,分别以'.'和'E'代替。有个1*1*2的长方体,在这上面滚动,要使它最后立在目标位置上(就是只占一格且在目标上),长方体初始位置用'X'表示,目标用'O'表示。

题解:bfs,记录长方体左上角的点的位置以及它的摆放位置(立着:0,横躺着:1,竖躺着:2),然后就可以用mark[505][505][3]的bool数组记录是否走过某点了。

View Code
  1 #include<cstdio>
  2 #include<cstring>
  3 #include<algorithm>
  4 using namespace std;
  5 const int N=505,M=1000000;
  6 char map[N][N];
  7 bool mark[N][N][3];
  8 int r,c;
  9 struct Data
 10 {
 11     int x,y,w,step;
 12 }S[M];
 13 bool in(int x,int y)
 14 {
 15     return x>=1&&x<=r&&y>=1&&y<=c;
 16 }
 17 bool place(int x,int y,int w)
 18 {
 19     if(!in(x,y)||map[x][y]=='#')
 20         return false;
 21     switch(w)
 22     {
 23         case 0:
 24             return map[x][y]!='E';break;
 25         case 1:
 26             return in(x,y+1)&&map[x][y+1]!='#';break;
 27         case 2:
 28             return in(x+1,y)&&map[x+1][y]!='#';break;
 29     }
 30 }
 31 int dr[][2]={0,1,1,0,0,-1,-1,0};
 32 int main()
 33 {
 34     while(scanf("%d%d",&r,&c),(r||c))
 35     {
 36         bool flag=false;
 37         Data a,b;
 38         for(int i=1; i<=r; i++)
 39         {
 40             scanf("%s",map[i]+1);
 41             for(int j=1; j<=c; j++)
 42             {
 43                 if(map[i][j]=='X')
 44                 {
 45                     if(flag)
 46                     {
 47                         if(in(i-1,j)&&map[i-1][j]=='X')
 48                             a.w=2;
 49                         else
 50                             a.w=1;
 51                     }
 52                     else
 53                     {
 54                         flag=true;
 55                         a.x=i;
 56                         a.y=j;
 57                         a.w=a.step=0;
 58                     }
 59                 }
 60             }
 61         }
 62         int st=0,ed=1;
 63         S[0]=a;
 64         memset(mark,false,sizeof(mark));
 65         mark[a.x][a.y][a.w]=true;
 66         while(st!=ed)
 67         {
 68             a=S[st++];
 69             if(st==M)
 70                 st=0;
 71             if(a.w==0&&map[a.x][a.y]=='O')
 72             {
 73                 flag=false;
 74                 printf("%d\n",a.step);
 75                 break;
 76             }
 77             for(int i=0;i<4;i++)
 78             {
 79                 b.x=a.x+dr[i][0];
 80                 b.y=a.y+dr[i][1];
 81                 b.step=a.step+1;
 82                 switch(a.w)
 83                 {
 84                     case 0:
 85                     {
 86                         switch(i)
 87                         {
 88                             case 0:
 89                                 b.w=1;break;
 90                             case 1:
 91                                 b.w=2;break;
 92                             case 2:
 93                                 b.w=1;b.y--;break;
 94                             case 3:
 95                                 b.w=2;b.x--;break;
 96                         }
 97                         break;
 98                     }
 99                     case 1:
100                     {
101                         switch(i)
102                         {
103                             case 0:
104                                 b.w=0;b.y++;break;
105                             case 1:
106                                 b.w=1;break;
107                             case 2:
108                                 b.w=0;break;
109                             case 3:
110                                 b.w=1;break;
111                         }
112                         break;
113                     }
114                     case 2:
115                     {
116                         switch(i)
117                         {
118                             case 0:
119                                 b.w=2;break;
120                             case 1:
121                                 b.x++;b.w=0;break;
122                             case 2:
123                                 b.w=2;break;
124                             case 3:
125                                 b.w=0;break;
126                         }
127                         break;
128                     }
129                 }
130                 if(place(b.x,b.y,b.w)&&!mark[b.x][b.y][b.w])
131                 {
132                     mark[b.x][b.y][b.w]=true;
133                     S[ed++]=b;
134                     if(ed==M)
135                         ed=0;
136                 }
137             }
138         }
139         if(flag)
140             printf("Impossible\n");
141     }
142     return 0;
143 }