diff --git a/thu2025kaoyan_b.cpp b/thu2025kaoyan_b.cpp new file mode 100644 index 0000000..4a8aebb --- /dev/null +++ b/thu2025kaoyan_b.cpp @@ -0,0 +1,322 @@ +#include +#include + +#define MAXN 550 +#define QSIZE (3 * 500 * 500) + +enum posture { + pos_s, + pos_h, + pos_v +}; + +struct q_node { + int row; + int col; + posture pos; +}; + +int T; +int n, m; +int dist_s[MAXN][MAXN], dist_h[MAXN][MAXN], dist_v[MAXN][MAXN]; + +q_node q[QSIZE]; +int q_head = 0; +int q_tail = 0; + +void q_clear() { + q_head = 0; + q_tail = 0; +} + +bool q_empty() { + return q_head == q_tail; +} + +void enq(q_node node) { + q[q_tail] = node; + q_tail++; + q_tail %= QSIZE; +} + +q_node deq() { + q_node ret = q[q_head]; + q_head++; + q_head %= QSIZE; + return ret; +} + +int start_row, start_col; +posture start_pos; +int end_row, end_col; + +int map[MAXN][MAXN] = {0}; +// 0 = wall +// 1 = ground + +bool valid_pos(int row, int col, posture pos) { + if (row >= n || col >= m || row < 0 || col < 0) { + return false; + } + if (pos == pos_s) { + return map[row][col] > 0; + } else if (pos == pos_h) { + return map[row][col] > 0 && map[row][col + 1] > 0; + } else if (pos == pos_v) { + return map[row][col] > 0 && map[row + 1][col] > 0; + } else { + // should not be here + return false; + } +} + +int bfs() { + // init + q_clear(); + for (int i = 0; i < n; ++i) { + for (int j = 0; j < m; ++j) { + dist_s[i][j] = -1; + dist_h[i][j] = -1; + dist_v[i][j] = -1; + } + } + + if (start_pos == pos_s) { + dist_s[start_row][start_col] = 0; + } else if (start_pos == pos_h) { + dist_h[start_row][start_col] = 0; + } else if (start_pos == pos_v) { + dist_v[start_row][start_col] = 0; + } + + q_node start_node = q_node { + .row = start_row, + .col = start_col, + .pos = start_pos, + }; + + enq(start_node); + + while (!q_empty()) { + q_node cur_node = deq(); + + if (cur_node.row == end_row && cur_node.col == end_col && cur_node.pos == pos_s) { + return dist_s[end_row][end_col]; + } + + // printf("%d,%d, pos %d\n", cur_node.row, cur_node.col, cur_node.pos); + + if (cur_node.pos == pos_s) { + int cur_dist = dist_s[cur_node.row][cur_node.col]; + // left + if (valid_pos(cur_node.row, cur_node.col - 2, pos_h)) { + if (dist_h[cur_node.row][cur_node.col - 2] == -1) { + dist_h[cur_node.row][cur_node.col - 2] = cur_dist + 1; + q_node new_node = q_node { + .row = cur_node.row, + .col = cur_node.col - 2, + .pos = pos_h, + }; + enq(new_node); + } + } + + // right + if (valid_pos(cur_node.row, cur_node.col + 1, pos_h)) { + if (dist_h[cur_node.row][cur_node.col + 1] == -1) { + dist_h[cur_node.row][cur_node.col + 1] = cur_dist + 1; + q_node new_node = q_node { + .row = cur_node.row, + .col = cur_node.col + 1, + .pos = pos_h, + }; + enq(new_node); + } + } + + // up + if (valid_pos(cur_node.row - 2, cur_node.col, pos_v)) { + if (dist_v[cur_node.row - 2][cur_node.col] == -1) { + dist_v[cur_node.row - 2][cur_node.col] = cur_dist + 1; + q_node new_node = q_node { + .row = cur_node.row - 2, + .col = cur_node.col, + .pos = pos_v, + }; + enq(new_node); + } + } + + // down + if (valid_pos(cur_node.row + 1, cur_node.col, pos_v)) { + if (dist_v[cur_node.row + 1][cur_node.col] == -1) { + dist_v[cur_node.row + 1][cur_node.col] = cur_dist + 1; + q_node new_node = q_node { + .row = cur_node.row + 1, + .col = cur_node.col, + .pos = pos_v, + }; + enq(new_node); + } + } + } else if (cur_node.pos == pos_h) { + int cur_dist = dist_h[cur_node.row][cur_node.col]; + // left + if (valid_pos(cur_node.row, cur_node.col - 1, pos_s)) { + if (dist_s[cur_node.row][cur_node.col - 1] == -1) { + dist_s[cur_node.row][cur_node.col - 1] = cur_dist + 1; + q_node new_node = q_node { + .row = cur_node.row, + .col = cur_node.col - 1, + .pos = pos_s, + }; + enq(new_node); + } + } + + // right + if (valid_pos(cur_node.row, cur_node.col + 2, pos_s)) { + if (dist_s[cur_node.row][cur_node.col + 2] == -1) { + dist_s[cur_node.row][cur_node.col + 2] = cur_dist + 1; + q_node new_node = q_node { + .row = cur_node.row, + .col = cur_node.col + 2, + .pos = pos_s, + }; + enq(new_node); + } + } + + // up + if (valid_pos(cur_node.row - 1, cur_node.col, pos_h)) { + if (dist_h[cur_node.row - 1][cur_node.col] == -1) { + dist_h[cur_node.row - 1][cur_node.col] = cur_dist + 1; + q_node new_node = q_node { + .row = cur_node.row - 1, + .col = cur_node.col, + .pos = pos_h, + }; + enq(new_node); + } + } + + // down + if (valid_pos(cur_node.row + 1, cur_node.col, pos_h)) { + if (dist_h[cur_node.row + 1][cur_node.col] == -1) { + dist_h[cur_node.row + 1][cur_node.col] = cur_dist + 1; + q_node new_node = q_node { + .row = cur_node.row + 1, + .col = cur_node.col, + .pos = pos_h, + }; + enq(new_node); + } + } + } else if (cur_node.pos == pos_v) { + int cur_dist = dist_v[cur_node.row][cur_node.col]; + // left + if (valid_pos(cur_node.row, cur_node.col - 1, pos_v)) { + if (dist_v[cur_node.row][cur_node.col - 1] == -1) { + dist_v[cur_node.row][cur_node.col - 1] = cur_dist + 1; + q_node new_node = q_node { + .row = cur_node.row, + .col = cur_node.col - 1, + .pos = pos_v, + }; + enq(new_node); + } + } + + // right + if (valid_pos(cur_node.row, cur_node.col + 1, pos_v)) { + if (dist_v[cur_node.row][cur_node.col + 1] == -1) { + dist_v[cur_node.row][cur_node.col + 1] = cur_dist + 1; + q_node new_node = q_node { + .row = cur_node.row, + .col = cur_node.col + 1, + .pos = pos_v, + }; + enq(new_node); + } + } + + // up + if (valid_pos(cur_node.row - 1, cur_node.col, pos_s)) { + if (dist_s[cur_node.row - 1][cur_node.col] == -1) { + dist_s[cur_node.row - 1][cur_node.col] = cur_dist + 1; + q_node new_node = q_node { + .row = cur_node.row - 1, + .col = cur_node.col, + .pos = pos_s, + }; + enq(new_node); + } + } + + // down + if (valid_pos(cur_node.row + 2, cur_node.col, pos_s)) { + if (dist_s[cur_node.row + 2][cur_node.col] == -1) { + dist_s[cur_node.row + 2][cur_node.col] = cur_dist + 1; + q_node new_node = q_node { + .row = cur_node.row + 2, + .col = cur_node.col, + .pos = pos_s, + }; + enq(new_node); + } + } + } else { + // Should not be here + } + } + return -1; +} + +int main() { + scanf("%d", &T); + for (int _ = 0; _ < T; ++_) { + // Initialize + memset(map, 0, sizeof(map)); + bool found_start = false; + scanf("%d %d", &n, &m); + + // Read in map + char linebuf[MAXN] = {0}; + for (int i = 0; i < n; ++i) { + scanf("%s", linebuf); + for (int j = 0; j < m; ++j) { + if (linebuf[j] == '#') { + map[i][j] = 0; + } else if (linebuf[j] == '.' || linebuf[j] == 'E') { + map[i][j] = 1; + } else if (linebuf[j] == 'X') { + map[i][j] = 1; + if (found_start == false) { + start_row = i; + start_col = j; + start_pos = pos_s; + // Assume this pos, if there are more X then change + found_start = true; + } else { + if (j == start_col + 1 && i == start_row) { + start_pos = pos_h; + } else if (j == start_col && i == start_row + 1) { + start_pos = pos_v; + } else { + // Should not be here + } + } + } else if (linebuf[j] == 'O') { + map[i][j] = 1; + end_row = i; + end_col = j; + } + } + } + + int ans = bfs(); + printf("%d\n", ans); + } + + return 0; +} \ No newline at end of file