2025考研b partial ac

This commit is contained in:
2025-08-25 11:58:06 +08:00
parent 560a6d5c0b
commit 05b5349c93

322
thu2025kaoyan_b.cpp Normal file
View File

@@ -0,0 +1,322 @@
#include <stdio.h>
#include <string.h>
#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;
}