201312-5 I'm stuck!
思路
从起点正向深搜,检查是否可以达到终点,并标记从起点可到达的点。
从终点反向深搜,标记终点可以到达的点。
起点可到达而终点不可到达的点符合要求。
代码
#include <iostream>
#define MAXN (1<<6)
using namespace std;
// 左, 上, 右, 下
int dx[4] = {0, -1, 0, 1};
int dy[4] = {-1, 0, 1, 0};
int Row, Col;
int sx, sy;
int tx, ty;
char map[MAXN][MAXN];
bool forward_dfs_visit[MAXN][MAXN];
bool back_dfs_visit[MAXN][MAXN];
void forward_dfs(int cur_row, int cur_col) {
if (cur_row < 0 || cur_row > Row
|| cur_col < 0 || cur_col > Col
|| forward_dfs_visit[cur_row][cur_col] == true) {
return;
}
int move_base, move_step;
switch (map[cur_row][cur_col]) {
case '+':
move_base = 0, move_step = 1;
break;
case '-':
move_base = 0, move_step = 2;
break;
case '|':
move_base = 1, move_step = 2;
break;
case '.':
move_base = 3, move_step = 1;
break;
default:
return;
}
forward_dfs_visit[cur_row][cur_col] = true;
int i;
for (i = move_base;i < 4;i += move_step) {
forward_dfs(cur_row + dx[i],cur_col + dy[i]);
}
}
void back_dfs(int cur_row, int cur_col) {
if (cur_row < 0 || cur_row > Row
|| cur_col < 0 || cur_col > Col
|| back_dfs_visit[cur_row][cur_col] == true) {
return;
}
back_dfs_visit[cur_row][cur_col] = true;
int i;
for (i = 0;i < 4;++i) {
switch (map[cur_row + dx[i]][cur_col + dy[i]]) {
case '+':
back_dfs(cur_row + dx[i],cur_col + dy[i]);
break;
case '-':
if (i == 0 || i == 2) {
back_dfs(cur_row + dx[i],cur_col + dy[i]);
}
break;
case '|':
if (i == 1 || i == 3) {
back_dfs(cur_row + dx[i],cur_col + dy[i]);
}
break;
case '.':
if (i == 1) {
back_dfs(cur_row + dx[i],cur_col + dy[i]);
}
break;
default:
continue;
}
}
}
int main() {
int sx, sy;
int tx, ty;
cin >> Row >> Col;
int i, j;
for (i = 0;i < Row;++i) {
for (j = 0;j < Col;++j) {
cin >> map[i][j];
if (map[i][j] == 'S') {
sx = i, sy = j;
} else if (map[i][j] == 'T') {
tx = i, ty = j;
}
}
}
map[sx][sy] = map[tx][ty] = '+';
forward_dfs(sx,sy);
if (forward_dfs_visit[tx][ty] == false) {
cout << "I'm stuck!";
return 0;
}
back_dfs(tx,ty);
int block_cnt = 0;
for (i = 0;i < Row;++i) {
for (j = 0; j < Col;++j) {
if (forward_dfs_visit[i][j] == true
&& back_dfs_visit[i][j] == false) {
++block_cnt;
}
}
}
cout << block_cnt;
}