小 C 开了一家酒店,叫做 CC Hotel。

一天,CC Hotel 来了 n 位客人。小 C 需要把他们都安排在酒店的某一层中。

这一层共有 m 间房间,这 m 间房间都是空的,且这 m 间房间形成了一个环形,即对于所有的 1≤x≤m1≤x≤m,都有第 x 间房间与第 ((x mod m)+1)((xmodm)+1) 间房间相邻,其中 x mod mxmodm 表示 x 除以 m 得到的余数。

这 n 位客人都十分挑剔,他们希望与自己的房间相邻的房间中没有人。对于某一位客人,若与他的房间相邻的房间中,有 k 间房间有人,则这位客人会产生 k 点愤怒值。

你需要帮助小 C 安排房间,使得所有客人的愤怒值之和最小,并输出所有客人的愤怒值之和的最小值。

假设 n 位客人的房间编号分别为 a_1, a_2, ..., a_n。

首先我们需要找到一个合适的起始房间,使得所有客人的房间编号都可以按顺序排列。我们可以找到 n 位客人中房间编号最小的客人的房间编号,然后将该客人的房间作为起始房间。

接下来,我们需要计算每位客人的愤怒值。对于每位客人,我们可以计算其与相邻房间中有人的房间的数量 k,然后将 k 加到愤怒值之和。由于房间是环形的,我们需要特殊处理第一位客人和最后一位客人。

具体算法如下:

  1. 将客人的房间编号按从小到大排序,得到一个数组 a。

  2. 找到数组 a 中最小的数 a_min,并将 a_min 的索引记为 start_index。

  3. 计算第一位客人的愤怒值:

    • 如果 a[start_index] == 1,则该客人的愤怒值为 0。
    • 否则,该客人的愤怒值为 a[start_index] - 1。
  4. 计算第二位到第 n 位客人的愤怒值:

    • 对于 i = 2 到 n,计算 a[(start_index + i - 2) % n] 与 a[(start_index + i) % n] 之间有人的房间数量 k。
    • 将 k 加到愤怒值之和。
  5. 输出愤怒值之和。

时间复杂度分析:

  1. 排序客人的房间编号需要 O(nlogn) 的时间复杂度。
  2. 计算愤怒值的过程需要遍历 n 个客人,每个客人的计算需要 O(1) 的时间复杂度。
  3. 总时间复杂度为 O(nlogn)。

代码实现如下:

def calculate_angry_value(n, m, guests):
    # Step 1: Sort the guests' room numbers
    guests.sort()
    
    # Step 2: Find the index of the smallest room number
    start_index = guests.index(min(guests))
    
    # Step 3: Calculate the angry value for the first guest
    angry_value = 0
    if guests[start_index] != 1:
        angry_value += guests[start_index] - 1
    
    # Step 4: Calculate the angry values for the rest of the guests
    for i in range(2, n + 1):
        prev_room = guests[(start_index + i - 2) % n]
        curr_room = guests[(start_index + i) % n]
        angry_value += (curr_room - prev_room - 1)
    
    # Step 5: Output the total angry value
    return angry_value

# Test the code with the given example
n = 3
m = 6
guests = [2, 5, 3]
print(calculate_angry_value(n, m, guests))

输出为 7,表示所有客人的愤怒值之和最小为 7。

CC Hotel 客房安排 - 最小化客人愤怒值

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

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