目录
一.题目简介
可以先玩一下这个游戏
点击打开链接
二.题解
这道题目就是波尔皮,很简单,就是爆搜一通,BFS直接暴力物体从起点到终点的全过程。
但是就一个难点,对于每一个状态的判重和转移。
首先,我们要明白有三种情况,分别是上面图片中的三种情况,我分别称其为:立(0)、横(2)、竖(1)。
然后由于有些状态的物体是躺着的,占据两个单位格子,我们可以强制把这种状态归为一个单位格子,并且只标记一个格子,我是横着就标记左面的格子,竖着就标记上面的格子,立着就不用说了,所以可以用一个三维的标记数组:第一维: 表示状态;第二维:第几行;第三维:第几列。
最后就是写方向函数,同样可以定义一个三维的dir数组:。表示:三种状态,每种状态有四种转移方式,这四种每种有三个变量:x坐标的转移,y坐标的转移,转移之后的状态。我定义了两个dir,第一个是转移要标记的格子,第二个是转移不标记的格子,因为我要判断它整个物体的放法是否合法。注意转移的时候的判断有点繁琐。
int dir1[3][4][3] = {//负责要标记的格子的转移
{{1, 0, 1}, {-2, 0, 1}, {0, -2, 2}, {0, 1, 2}},
{{2, 0, 0}, {-1, 0, 0}, {0, -1, 1}, {0, 1, 1}},
{{-1, 0, 2}, {1, 0, 2}, {0, -1, 0}, {0, 2, 0}},
};
int dir2[3][4][3] = {//负责不标记的格子的转移
{{2, 0, 1}, {-1, 0, 1}, {0, -1, 2}, {0, 2, 2}},
{{2, 0, 0}, {-1, 0, 0}, {1, -1, 1}, {1, 1, 1}},
{{-1, 1, 2}, {1, 1, 2}, {0, -1, 0}, {0, 2, 0}},
};
三.代码
#include <cstdio>
#include <cstring>
#include <iostream>
#include <queue>
using namespace std;
int r, c, sx[3], sy[3], k;
bool flag, vis[3][505][505];
int dir1[3][4][3] = {
{{1, 0, 1}, {-2, 0, 1}, {0, -2, 2}, {0, 1, 2}},
{{2, 0, 0}, {-1, 0, 0}, {0, -1, 1}, {0, 1, 1}},
{{-1, 0, 2}, {1, 0, 2}, {0, -1, 0}, {0, 2, 0}},
};
int dir2[3][4][3] = {
{{2, 0, 1}, {-1, 0, 1}, {0, -1, 2}, {0, 2, 2}},
{{2, 0, 0}, {-1, 0, 0}, {1, -1, 1}, {1, 1, 1}},
{{-1, 1, 2}, {1, 1, 2}, {0, -1, 0}, {0, 2, 0}},
};
char G[505][505];
struct node {
int x, y, d, step;
};
bool pd (int tox, int toy){
if (tox < 1 || tox > r || toy < 1 || toy > c || G[tox][toy] == '#')
return 0;
return 1;
}
void BFS (){
queue <node> f;
node t1, t2;
if (k == 1)//特判物体的起始状态
t1.d = 0;
else
if (sx[1] == sx[2] - 1)
t1.d = 1;
else
t1.d = 2;
t1.x = sx[1], t1.y = sy[1], t1.step = 0;
vis[t1.d][t1.x][t1.y] = 1;
f.push (t1);
while (! f.empty ()){
t1 = f.front ();
f.pop ();
if (t1.d == 0 && G[t1.x][t1.y] == 'O'){
printf ("%d\n", t1.step);
flag = 1;
return ;
}
for (int i = 0; i < 4; i ++){
int tox1 = dir1[t1.d][i][0] + t1.x;
int toy1 = dir1[t1.d][i][1] + t1.y;
int tox2 = dir2[t1.d][i][0] + t1.x;
int toy2 = dir2[t1.d][i][1] + t1.y;
if (dir1[t1.d][i][2] == 0 && G[tox1][toy1] == 'E')
continue;
if (pd (tox1, toy1) && pd (tox2, toy2) && ! vis[dir1[t1.d][i][2]][tox1][toy1]){
t2.x = tox1, t2.y = toy1, t2.step = t1.step + 1;
t2.d = dir1[t1.d][i][2];
vis[t2.d][t2.x][t2.y] = 1;
f.push (t2);
}
}
}
}
int main (){
while (scanf ("%d %d", &r, &c) && r != 0 && c != 0){
memset (vis, 0, sizeof (vis));
flag = 0;
k = 0;
for (int i = 1; i <= r; i ++){
getchar ();
for (int j = 1; j <= c; j ++){
scanf ("%c", &G[i][j]);
if (G[i][j] == 'X')
sx[++ k] = i, sy[k] = j;
}
}
BFS ();
if (! flag)
printf ("Impossible\n");
}
return 0;
}