这个题目很容易超时,要注意以下几个点:
①check最好不要使用多次,因为check本身是很费时间的,在bfs里面多次运用容易超时
②起点不需要check,因为起点3×3内肯定无障碍,不然胖子都装不下了
③有一次90%通过率,另外一个运行超时,找了很久原因,后面把这两行代码改成一行就行: x,y,state,time = q[0] q.pop(0)
可以直接改成我代码中的即可: x,y,state,time =q.pop(0) 这样就会省下时间就不会运行超时了
n,k = map(int,input().split())
maps = [list(input()) for _ in range(n)]
walked = [[0]*n for _ in range(n)] #走过的路变成1
walked[2][2] = 1 # 起点
q = [(2,2,5,0)] # 队列:x,y,state,time state有5,3,1
def next_state(time):
"根据步数查看胖子大小"
if time < k:
return 5
elif time < 2*k:
return 3
else:
return 1
def check(x,y,state):
"检查[x,y]在state范围内是否障碍"
change = state//2 # 变动的值,比如[2,2]的时候如果查5×5的范围,那就是5//2=2,[0,4]
for i in range(x-change,x+change+1): #范围从[x-change,x+change] [0,4]
for j in range(y-change,y+change+1): # 搜索state范围内
if 0<=i<=n-1 and 0<=j<=n-1: #如果不超过范围
if maps[i][j] == "*": #存在障碍
return False
else:
return False
return True
def bfs():
"bfs寻找最短路径"
while q:
x,y,state,time = q.pop(0) # 取出第一个值并删除
for dx,dy in [1,0],[0,1],[-1,0],[0,-1]: # 四个方向走
nx = x + dx
ny = y + dy
if check(nx,ny,state) and walked[nx][ny] == 0: #下一步能走且没走过
if nx == n-3 and ny == n-3: # 9的话 起点[2,2] 终点[6,6]
return time+1 # 下一步是终点就直接返回时间+1
q.append((nx,ny,next_state(time+1),time+1)) # 新信息加入队列
walked[nx][ny] = 1 # 走过的路变成1
if state != 1: # 不是瘦子的话就存在不走的情况,瘦子就肯定会走,上下左右总有一个能走
q.append((x,y,next_state(time+1),time+1))
return -1
print(bfs())