POJ3322 Bloxorz I

Bloxorz I
Time Limit: 2000MS   Memory Limit: 65536K
Total Submissions: 5993   Accepted: 1976

Description

Little Tom loves playing games. One day he downloads a little computer game called 'Bloxorz' which makes him excited. It's a game about rolling a box to a specific position on a special plane. Precisely, the plane, which is composed of several unit cells, is a rectangle shaped area. And the box, consisting of two perfectly aligned unit cube, may either lies down and occupies two neighbouring cells or stands up and occupies one single cell. One may move the box by picking one of the four edges of the box on the ground and rolling the box 90 degrees around that edge, which is counted as one move. There are three kinds of cells, rigid cells, easily broken cells and empty cells. A rigid cell can support full weight of the box, so it can be either one of the two cells that the box lies on or the cell that the box fully stands on. A easily broken cells can only support half the weight of the box, so it cannot be the only cell that the box stands on. An empty cell cannot support anything, so there cannot be any part of the box on that cell. The target of the game is to roll the box standing onto the only target cell on the plane with minimum moves.


The box stands on a single cell

The box lies on two neighbouring cells, horizontally

The box lies on two neighbouring cells, vertically

After Little Tom passes several stages of the game, he finds it much harder than he expected. So he turns to your help.

Input

Input contains multiple test cases. Each test case is one single stage of the game. It starts with two integers R and C(3 ≤ R, C ≤ 500) which stands for number of rows and columns of the plane. That follows the plane, which contains R lines and C characters for each line, with 'O' (Oh) for target cell, 'X' for initial position of the box, '.' for a rigid cell, '#' for a empty cell and 'E' for a easily broken cell. A test cases starts with two zeros ends the input.

It guarantees that

  • There's only one 'O' in a plane.
  • There's either one 'X' or neighbouring two 'X's in a plane.
  • The first(and last) row(and column) must be '#'(empty cell).
  • Cells covered by 'O' and 'X' are all rigid cells.

Output

For each test cases output one line with the minimum number of moves or "Impossible" (without quote) when there's no way to achieve the target cell.  

Sample Input

7 7
#######
#..X###
#..##O#
#....E#
#....E#
#.....#
#######
0 0

Sample Output

10

Source

 
 
【翻译】
(非博主翻译)
šBloxorz是一个风靡世界的小游戏。Bloxorz的地图是一个N行M列的矩阵,每个位置可能是硬地(用.表示)、易碎地面(用E表示)、禁地(用#表示)、起点(用X表示)或终点(用O表示)。你的任务是操作一个1*1*2的长方体。这个长方体在地面上有两种放置形式,“立”在地面上(1*1的面接触地面)或者“躺”在地面上(1*2的面接触地面)。在每一步操作中,可以按上下左右四个键之一。按下之后,长方体向对应的方向沿着棱滚动90度。任意时刻,长方体不能有任何部位接触禁地(否则就会掉下去),并且不能立在易碎地面上(否则会因为压强太大掉下去)。X标识长方体的起始位置,地图上可能有一个X或者两个相邻的X。地图上唯一的一个O标识目标位置。求把长方体移动到目标位置(即立在O上)所需要的最少步数。如果无解,输出Impossible。在移动过程中,X和O标识的位置都可以看作是硬地被利用,3<=N,M<=500。
【题解】
爆搜,没啥好说的
 
Code
  1 #include <iostream>
  2 #include <cstdio>
  3 #include <cstdlib>
  4 #include <cstring>
  5 #include <queue>
  6 #include <algorithm>
  7 
  8 inline void read(int &x)
  9 {
 10     x = 0;char ch = getchar();
 11     char c = ch;
 12     while(ch > '9' || ch < '0')c = ch, ch = getchar();
 13     while(ch <= '9' && ch >= '0')x = x * 10 + ch - '0', ch = getchar();
 14     if(c == '-')x = -x;
 15 }
 16 inline int min(int a, int b){return a > b ? b : a;}
 17 inline int max(int a, int b){return a > b ? a : b;}
 18 
 19 const int INF = 0x3f3f3f3f; 
 20 const int MAXN = 1000 + 10;
 21 const int MAXM = 1000 + 10;
 22 
 23 //0:一个点竖着,记录这个点的下标
 24 //1:竖着躺 记录上面的那个点的坐标
 25 //2:横着躺 记录左边的那个点的坐标 
 26 const int dx[3][4] = {{-2,1,0,0},{-1,2,0,0},{0,0,-1,1}}; 
 27 const int dy[3][4] = {{0,0,-2,1},{0,0,-1,1},{-1,2,0,0}};
 28 const int dz[3][4] = {{1,1,2,2},{0,0,1,1},{0,0,2,2}};
 29 
 30 char g[MAXN][MAXM];
 31 int n,m,sx,sy,sz,ex,ey;
 32 
 33 struct Point
 34 {
 35     int x,y,z,step;
 36     Point(){}
 37     Point(int _x, int _y, int _z, int _step){x = _x;y = _y;z = _z;step = _step;}
 38 };
 39 
 40 std::queue<Point> q;
 41 int b[MAXN][MAXM][4];
 42 
 43 int Isok(Point a)
 44 {
 45     if(a.z == 0 && !(a.x > n || a.x < 1 || a.y > m || a.y < 1) && !b[a.x][a.y][a.z] && g[a.x][a.y] != 'E' && g[a.x][a.y] != '#')return 0;
 46     if(a.z == 1 && !(a.x < 1 || a.x + 1 > n || a.y < 1 || a.y > m) && !b[a.x][a.y][a.z] && g[a.x][a.y] != '#' && g[a.x + 1][a.y] != '#')return 0;
 47     if(a.z == 2 && !(a.x < 1 || a.x > n || a.y < 1 || a.y + 1 > m) && !b[a.x][a.y][a.z] && g[a.x][a.y] != '#' && g[a.x][a.y + 1] != '#')return 0;
 48     return 1;
 49 }
 50 
 51 int bfs()
 52 {
 53     memset(b, 0, sizeof(b));
 54     while(q.size())q.pop();
 55     q.push(Point(sx, sy, sz, 0));
 56     Point now;
 57     b[sx][sy][sz] = true;
 58     while(q.size())
 59     {
 60         now = q.front();q.pop();
 61         for(int i = 0;i < 4;++ i)
 62         {
 63             Point tmp;
 64             tmp = Point(now.x + dx[now.z][i],now.y + dy[now.z][i], dz[now.z][i], now.step + 1);
 65             if(Isok(tmp)) continue;
 66             if(tmp.x == ex && tmp.y == ey && !tmp.z)return tmp.step;
 67             q.push(tmp);
 68             b[tmp.x][tmp.y][tmp.z] = 1;
 69         }
 70     }
 71     return -1;
 72 }
 73 
 74 int main()
 75 {
 76     while (scanf("%d %d", &n, &m) && n)
 77     {
 78         for(int i = 1;i <= n;++ i)
 79             scanf("%s", g[i] + 1);
 80         for (int i = 1;i <= n;++ i)
 81         {
 82             for (int j = 1;j <= m;++ j)
 83                 if (g[i][j] == 'O')
 84                     ex = i,ey = j;
 85                 else if (g[i][j] == 'X' && g[i + 1][j] == 'X')
 86                 {
 87                     sx = i,sy = j;
 88                     g[i + 1][j] = '.';
 89                     sz = 1;
 90                 }
 91                 else if(g[i][j] == 'X' && g[i][j + 1] == 'X')
 92                 {
 93                     g[i][j + 1] = '.';
 94                     sx = i,sy = j;
 95                     sz = 2;
 96                 }
 97                 else if(g[i][j] == 'X')
 98                 {
 99                     sx = i,sy = j;
100                     sz = 0;
101                 }
102         }
103         int ans = bfs();
104         if(ans == -1)puts("Impossible\n");
105         else printf("%d\n", ans);
106     }
107     return 0;
108 }
View Code

 

 
posted @ 2017-07-09 19:48  嘒彼小星  阅读(943)  评论(0编辑  收藏  举报