NOIP2012 提高组 借教室 - 详细解析与 Python 代码实现

在大学期间,经常需要租借教室。大到院系举办活动,小到学习小组自习讨论,都需要向学校申请借教室。教室的大小功能不同,借教室人的身份不同,借教室的手续也不一样。

面对海量租借教室的信息,我们自然希望编程解决这个问题。

我们需要处理接下来 'n' 天的借教室信息,其中第 'i' 天学校有 'r_i' 个教室可供租借。共有 'm' 份订单,每份订单用三个正整数描述,分别为 'd_j,s_j,t_j',表示某租借者需要从第 's_j' 天到第 't_j' 天租借教室(包括第 's_j' 天和第 't_j' 天),每天需要租借 'd_j' 个教室。

我们假定,租借者对教室的大小、地点没有要求。即对于每份订单,我们只需要每天提供 'd_j' 个教室,而它们具体是哪些教室,每天是否是相同的教室则不用考虑。

借教室的原则是先到先得,也就是说我们要按照订单的先后顺序依次为每份订单分配教室。如果在分配的过程中遇到一份订单无法完全满足,则需要停止教室的分配,通知当前申请人修改订单。这里的无法满足指从第 's_j' 天到第 't_j' 天中有至少一天剩余的教室数量不足 'd_j' 个。

现在我们需要知道,是否会有订单无法完全满足。如果有,需要通知哪一个申请人修改订单。

解题思路

首先,我们可以使用一个数组 room 来记录每天可用的教室数量。

然后,我们按照订单的先后顺序依次处理每份订单。对于每份订单,我们需要判断从第 s_j 天到第 t_j 天中的教室数量是否足够。

为了方便计算,我们可以使用一个数组 sum 来记录每天的教室数量累加和。即 sum[i] 表示第 'i' 天之前(包括第 'i' 天)可用的教室数量总和。

然后,我们可以计算从第 's_j' 天到第 't_j' 天中的教室数量总和,即 sum[t_j] - sum[s_j-1]。如果这个总和小于订单中需要的教室数量 'd_j',则订单无法完全满足,需要通知当前申请人修改订单。

具体的算法步骤如下:

  1. 读取输入,初始化数组 room 和数组 sum
  2. 遍历每份订单,对于每份订单:
    • 计算从第 's_j' 天到第 't_j' 天中的教室数量总和 sum[t_j] - sum[s_j-1]
    • 如果这个总和小于订单中需要的教室数量 'd_j',则输出 '-1',并输出当前申请人的编号。
  3. 如果所有订单均满足,输出 '0'。

算法实现

n, m = map(int, input().split())
room = list(map(int, input().split()))

sum = [0] * (n+1)
for i in range(1, n+1):
    sum[i] = sum[i-1] + room[i-1]

for j in range(m):
    d, s, t = map(int, input().split())
    if sum[t] - sum[s-1] < d:
        print(-1)
        print(j+1)
        exit()

print(0)

复杂度分析

该算法的时间复杂度为 O(n+m),其中 n 是天数,m 是订单数量。这是因为需要遍历每份订单,并计算从第 s_j 天到第 t_j 天中的教室数量总和。同时,需要遍历每天可用的教室数量,计算累加和。

空间复杂度为 O(n),主要是用于存储每天的教室数量累加和。

总结

本篇博客详细解析了 NOIP2012 提高组 借教室问题的解题思路,并提供了 Python 代码实现,使用前缀和与差分,时间复杂度为 O(M + N),帮助你更好地理解算法并掌握解题技巧。希望这篇博客能对你有所帮助!

NOIP2012 提高组 借教室 - 详细解析与 Python 代码实现

原文地址: https://www.cveoy.top/t/topic/eO9g 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录