题目分析
被题目标题吸引进来的【史塔克的倔强】
题如其名,够繁琐冗长
能否到达T点很容易判断
输出满足条件的点需要双向bfs
经验总结
容易想到(自然的思路):从S开始用bfs遍历,从T再用bfs遍历,分别将图中的所有点用两
个状态数组表示,最后遍历图——前者标记过而后者没标记过的点即为答案(去除#点)。
但是!
很重要的一点——由某点到T和由T到某点是不一样的,是反向的!我就是直接傻乎乎地正向遍历两次(答案能对就怪了)。
双向BFS!!!
Python3 代码
from collections import deque
r, c = map(int, input().split())
g = []
for i in range(r):
g.append(list(input()))
qs = deque()
qt = deque()
sts = [[False for _ in range(c)] for _ in range(r)]
stt = [[False for _ in range(c)] for _ in range(r)]
# 初始化起始点和终点
start = end = None
for i in range(r):
for j in range(c):
if g[i][j] == 'S':
qs.append((i, j))
sts[i][j] = True
start = (i, j)
if g[i][j] == 'T':
end = (i, j)
qt.append((i, j))
stt[i][j] = True
if g[i][j] == '#':
sts[i][j] = True
stt[i][j] = True
dx = [0, 0, 1, -1]
dy = [1, -1, 0, 0]
flag = 0
# 处理S的正向BFS
while qs:
t = qs.popleft()
if g[t[0]][t[1]] == 'T':
flag = 1
cell_type = g[t[0]][t[1]]
directions = []
if cell_type in ['+', 'S', 'T']:
directions = [0, 1, 2, 3]
elif cell_type == '-':
directions = [0, 1]
elif cell_type == '|':
directions = [2, 3]
elif cell_type == '.':
directions = [2]
for i in directions:
nx = t[0] + dx[i]
ny = t[1] + dy[i]
if 0 <= nx < r and 0 <= ny < c and not sts[nx][ny]:
sts[nx][ny] = True
qs.append((nx, ny))
if not flag:
print("I'm stuck!")
exit()
# 处理T的逆向BFS
while qt:
t = qt.popleft()
for i in range(4):
nx = t[0] + dx[i]
ny = t[1] + dy[i]
if 0 <= nx < r and 0 <= ny < c and not stt[nx][ny]:
# 检查nx, ny是否可以移动到t的位置
parent_type = g[nx][ny]
valid = False
if parent_type == '#':
continue
if parent_type in ['+', 'S', 'T']:
valid = True
elif parent_type == '-':
if i == 0 or i == 1: # 左右方向
valid = True
elif parent_type == '|':
if i == 2 or i == 3: # 上下方向
valid = True
elif parent_type == '.':
if i == 3: # 只能向上移动(原向下)
valid = True
if valid:
stt[nx][ny] = True
qt.append((nx, ny))
ans = 0
for i in range(r):
for j in range(c):
if g[i][j] != '#' and sts[i][j] and not stt[i][j]:
ans += 1
print(ans)