【POJ3322】Bloxorz I

一道非常棒的搜索题,做完之后感觉神清气爽……

可以肯定的是,本题属于走地图一类的搜索题,适合用bfs求解,然而本题细节极多,有很多需要注意的地方。

我们定义状态三元组(x,y,z)表示当前移动到位置(x,y),且朝向z(我们不妨假定z=0意味着长方体立在地面上,z=1 意味着长方体横躺,x,y表示左边长方体的位置;z=2意味着长方体竖躺,x,y表示上边长方体的位置)。同时,我们读入之后处理起点和终点,并加入队列。我们还要处理关于移动的常量数组(本题的关键),这样我们就可以进行bfs了,但是本题虽然思路简单,但是细节繁多,实现起来有一定难度。

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <queue>
 5 using namespace std;
 6 struct node {
 7     int x,y,z;
 8 }s,t;
 9 queue<node> q;
10 int n,m,dis[510][510][4];
11 char map[510][510];
12 const int fx[4]={0,0,-1,1};
13 const int fy[4]={-1,1,0,0};
14 const int nx[3][4]={{0,0,-2,1},{0,0,-1,1},{0,0,-1,2}};
15 const int ny[3][4]={{-2,1,0,0},{-1,2,0,0},{-1,1,0,0}};
16 const int nz[3][4]={{1,1,2,2},{0,0,1,1},{2,2,0,0}};
17 inline bool can(int x,int y) {
18     return x>=1&&x<=n&&y>=1&&y<=m;
19 }
20 inline bool can(node now) {
21     if(!can(now.x,now.y)) return 0;
22     if(map[now.x][now.y]=='#') return 0;
23     if(now.z==0&&map[now.x][now.y]!='.') return 0;
24     if(now.z==1&&map[now.x][now.y+1]=='#') return 0;
25     if(now.z==2&&map[now.x+1][now.y]=='#') return 0;
26     return 1;
27 }
28 void pre() {
29     for(int i=1;i<=n;i++) 
30         for(int j=1;j<=m;j++) {
31             if(map[i][j]=='O') {
32                 map[i][j]='.';
33                 t.x=i; t.y=j; t.z=0;
34             }
35             else if(map[i][j]=='X') {
36                 for(int k=0;k<4;k++) {
37                     int xx=i+fx[k];
38                     int yy=j+fy[k];
39                     if(can(xx,yy)&&map[xx][yy]=='X') {
40                         s.x=min(i,xx); s.y=min(j,yy);
41                         s.z=k<2?1:2;
42                         map[xx][yy]=map[i][j]='.';
43                         break ;
44                     }
45                 }
46                 if(map[i][j]=='X') s.x=i,s.y=j,s.z=0;
47             }
48         }
49 }
50 void bfs() {
51     dis[s.x][s.y][s.z]=0;
52     q.push(s);
53     while(!q.empty()) {
54         node now=q.front();
55         q.pop();
56         for(int i=0;i<4;i++) {
57             node neww;
58             neww.x=now.x+nx[now.z][i];
59             neww.y=now.y+ny[now.z][i];
60             neww.z=nz[now.z][i];
61             if(!can(neww)) continue ;
62             if(dis[neww.x][neww.y][neww.z]==-1) {
63                 dis[neww.x][neww.y][neww.z]=dis[now.x][now.y][now.z]+1;
64                 q.push(neww);
65                 if(neww.x==t.x&&neww.y==t.y&&neww.z==t.z) {
66                     printf("%d\n",dis[neww.x][neww.y][neww.z]);
67                     return ;
68                 }
69             }
70         }
71     }
72     puts("Impossible");
73 }
74 int main() {
75     while(cin>>n>>m&&n+m) {
76         for(int i=1;i<=n;i++)    scanf("%s",map[i]+1);
77         pre();
78         memset(dis,-1,sizeof(dis));
79         while(!q.empty()) q.pop();
80         bfs();
81     }
82     return 0;
83 } 
AC Code

 

posted @ 2019-04-14 11:13  AD_shl  阅读(231)  评论(0编辑  收藏  举报