📜  门|门 CS 1999 |第 56 题(1)

📅  最后修改于: 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的最小代价和。请计算每个位置的距离。

输入描述
  • 第一行,整数n(2≤n≤1000)。
  • 第二行,n个用空格分开的整数表示数组a。
输出描述
  • 输出n行,分别描述每个位置到1的最小代价和。
示例

输入:

8 
1 0 1 0 0 1 1 1

输出:

0
1
0
3
2
0
0
0

解题思路

本题要求求出每个门到1号门的最短路长度。对于一个门i,存在两种情况:

  • 当ai=1时,直接从i到i+1至i+4中的任一位置,到达花费为1。
  • 当ai=0时,需要先到达1号门,并且代价k为从i到1号门的最短路长度。

对于第一种情况,可以用贪心思路,从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实现,结果只供参考。