📅  最后修改于: 2023-12-03 15:12:46.128000             🧑  作者: Mango
本题题号为门|门 CS 1999 |第 56 题,是一道算法题目。该题可能出现在笔试、面试等场景中,适合于有一定算法基础的程序员。
给定一个长度为n的整型数组a,其中每个元素的值范围都在[0,100]之间,现在假定数组a代表一个道路,a[i]表示第i个位置上的门的状态:0表示门关着,1表示门开着。一开始,只有1号门是开着的,其它门都是关着的。你可以执行如下操作:从当前位置i出发,如果ai=1,那么可以直接到达ai+1至ai+4中的任一位置,到达花费为1;如果ai=0,那么需要付出由ai到ai+1的代价k。注意,只有当ai=0时才存在代价,且代价是动态变化的。具体地,当ai=0时,k为从i到1号门的最短路长度,到达1号门的代价为0。一个位置i的距离定义为从初始位置1到i的最小代价和。请计算每个位置的距离。
输入:
8
1 0 1 0 0 1 1 1
输出:
0
1
0
3
2
0
0
0
本题要求求出每个门到1号门的最短路长度。对于一个门i,存在两种情况:
对于第一种情况,可以用贪心思路,从1号门开始,依次向后遍历,每遇到一个开着的门,就更新它相邻的4个门到1号门的距离,直至遍历完所有门。
对于第二种情况,需要先计算出从1号门到每个0门的最短路长度,这里可以使用BFS求解,并通过记忆化的方式,减少重复计算。
在实现上,可以使用两个队列,分别存储当前花费为0的门以及花费不为0的门。每次从队列中取出一个门,如果它的状态为0,则计算从它到1号门的最短路长度,并将花费不为0的相邻4个门加入到队列中;如果它的状态为1,则跳过。
最终得到每个门到1号门的最短路长度,即为题目要求的每个位置到1的最小代价和。
import queue
INF = 0x3f3f3f3f
def bfs(n, a):
vis = [False] * (n + 1)
dist = [INF] * (n + 1)
q0 = queue.Queue()
q1 = queue.Queue()
q0.put(1)
dist[1] = 0
vis[1] = True
while not q0.empty() or not q1.empty():
while not q0.empty():
u = q0.get()
for v in range(u + 1, u + 5):
if v > n:
break
if not vis[v] and a[v] == 0:
q0.put(v)
vis[v] = True
dist[v] = dist[u] + 1
elif a[v] == 1:
break
while not q1.empty():
u = q1.get()
for v in range(u + 1, u + 5):
if v > n:
break
if not vis[v]:
q1.put(v)
vis[v] = True
dist[v] = dist[u] + 1
return dist
def solve(n, a):
dist = bfs(n, a)
for i in range(1, n + 1):
if a[i] == 0:
print(dist[i])
else:
cur = INF
for j in range(i + 1, min(i + 5, n + 1)):
cur = min(cur, dist[j])
print(cur)
n = int(input().strip())
a = [int(x) for x in input().strip().split()]
solve(n, a)
注:此处为python实现,结果只供参考。