题目:Link
代码:
#include <iostream>
#include <cstring>
#include <queue>
using namespace std;
struct rec {
int x, y, lie;
};
#define maxn 505
#define int long long
#define _for(i, a, b) for (int i = (a); i <= (b); i++)
const int dx[] = { 0,0,-1,1 };
const int dy[] = { -1,1,0,0 };
const int next_x[3][4] = { { 0,0,-2,1 },
{ 0,0,-1,1 },
{ 0,0,-1,2 } };
const int next_y[3][4] = { { -2,1,0,0 },
{ -1,2,0,0 },
{ -1,1,0,0 } };
const int next_lie[3][4] = { { 1,1,2,2 },
{ 0,0,1,1 },
{ 2,2,0,0 } };
int n, m;
int vis[maxn][maxn][3], ans[maxn][maxn][3];
char s[maxn][maxn];
queue<rec> q;
rec st, ed;
char read() {
char ch = getchar();
while(ch != 'O' && ch != 'X' && ch != '.' && ch != 'E' && ch != '#')
ch = getchar();
return ch;
}
bool valid1(int x, int y) {
if (x < 0 || y < 0 || x >= n || y >= m)
return false;
return true;
}
bool valid2(rec l) {
if (!valid1(l.x, l.y)) return false;
if (l.lie == 0 && (s[l.x][l.y] == '#' || s[l.x][l.y] == 'E')) return false;
if (l.lie == 1 && (s[l.x][l.y] == '#' || s[l.x][l.y + 1] == '#')) return false;
if (l.lie == 2 && (s[l.x][l.y] == '#' || s[l.x + 1][l.y] == '#')) return false;
return true;
}
void parse_st_ed() {
_for (i, 0, n)
_for (j, 0, m)
if (s[i][j] == 'O')
ed.x = i, ed.y = j, ed.lie = 0, s[i][j] = '.';
_for (i, 0, n)
_for (j, 0, m) {
if (s[i][j] == 'X') {
_for (k, 0, 3) {
int x = i + dx[k], y = j + dy[i];
if (valid1(x, y) && s[x][y] == 'X') {
st.x = min(x, i), st.y = min(y, j), st.lie = (k > 2) ? 2 : 1;
s[i][j] = s[x][y] = '.';
}
}
if (s[i][j] == 'X')
st.x = i, st.y = j, st.lie = 0, s[i][j] = '.';
}
}
}
void bfs() {
memset(vis, 0, sizeof(vis));
ans[st.x][st.y][st.lie] = 0;
q.push(st);
while(!q.empty()) {
rec l = q.front(); q.pop();
if (l.x == ed.x && l.y == ed.y && l.lie == ed.lie) {cout << ans[l.x][l.y][l.lie] << endl; return;}
_for (i, 0, 3) {
int x = l.x + next_x[l.lie][i];
int y = l.y + next_y[l.lie][i];
int lie = next_lie[l.lie][i];
rec u;
u.x = x, u.y = y, u.lie = lie;
if (!valid2(u) || vis[x][y][lie])
continue;
vis[x][y][lie] = true;
ans[x][y][lie] = ans[l.x][l.y][l.lie] + 1;
}
}
cout << "Impossible" << endl;
}
signed main() {
cin >> n >> m;
while (n != 0 && m != 0) {
while (!q.empty()) q.pop();
memset(ans, -1, sizeof(ans));
_for (i, 1, n) _for (j, 1, m) s[i][j] = read();
parse_st_ed();
bfs();
cin >> n >> m;
}
return 0;
}