【问题标题】:Minimum number of increment-other operations to make all array elements equal使所有数组元素相等的最小增量-其他操作数
【发布时间】:2018-01-03 19:05:08
【问题描述】:

我正在阅读极客网站上的this 问题。

问题是关于找出数组中的最小移动次数,以便所有元素都相等。

给定一个由 n 个元素组成的数组。在每次操作中,您 可以选择任何一个元素并将其余 n-1 个元素增加 1。你 必须使所有元素平等地执行这样的操作 你希望的时间。找出为此所需的最少操作数。

Examples:

Input : arr[] = {1, 2, 3}
Output : Minimum Operation = 3
Explanation : 
operation | increased elements | after increment
    1     |    1, 2            | 2, 3, 3
    2     |    1, 2            | 3, 4, 3
    3     |    1, 3            | 4, 4, 4

Input : arr[] = {4, 3, 4}
Output : Minimum Operation = 2
Explanation : 
operation | increased elements | after increment
     1    |    1, 2           | 5, 4, 4
     2    |    2, 3           | 5, 5, 5

链接说明我们必须使用公式minOperation = sum - (n * small) 来得到答案,其中 sum 是数组中所有元素的总和,n 是数组中元素的数量,small 是数组中的最小元素。

你能帮我理解一下minOperation = sum - (n * small)这个公式的含义吗?以及它是如何解决问题的?

【问题讨论】:

  • 这和Java有什么关系?如果是这样,则您的索引全部减一。
  • 想想数组的条形图,其中sum 是阴影部分的面积。 n*small 是由最小元素构成的基线下方的区域。区别 minOperation 是您需要删除的区域单位数,以使所有元素与基线匹配(每次操作都会增加)。
  • 一个可靠的算法可能是总是选择数组中第二小的元素,一个一个地增加与基线匹配的元素的数量。
  • "如果我们仔细研究每个操作以及问题陈述,我们会发现增加除最大元素之外的所有 n-1 个元素类似于仅减少最大元素。因此,最小元素不需要再减少,其余元素将减少到最小的一个。这样,使所有元素相等所需的操作总数将是......” - 这对我来说似乎很清楚。
  • 将元素 B 减少到 A 需要 B-A 操作,将 2 个元素 B 和 C 减少到 A 需要 B-A + C-A = B+C-2*A 操作。概括一下,你就有了你的公式。

标签: java arrays algorithm


【解决方案1】:

编辑 1: 为了更好地与此解决方案相关联,最好提及用户 Dukeling 在他的 cmets 中所说的话。也就是说,增加除最大元素之外的所有其他元素类似于仅减少最大元素。


现在,假设您正在尝试平整许多砖柱。每列砖块可以有不同的等级:

为了调平所有砖柱,您总是选择最高的一列并一次移除 1 块砖。

重复这个过程,直到所有列都被调平。

黄色是实现目标需要移除的积木。(它们也表示实现目标所需执行的操作数)

为了计算红砖的数量,你可以使用一个类似于矩形面积的简单公式,即长 x 宽。

min x number of columns = all the red bricks (to be remained untouched)

sum of all bricks - number of red bricks = all yellow bricks 

因此你有公式:

minOperation = sum - (n * small) 

黄色数 = 使所有数组元素相等所需的最少操作数。

【讨论】:

  • 这是我找到的最好的解释,视觉效果也很棒!谢谢
【解决方案2】:

使用一个简单的公式:

数组元素的总和 - (数组的大小 * 数组中的最小元素)

示例 array = {1, 2, 3, 4, 5} n = 5 // 数组大小

总和 = 15,最小值 = 1

ans = sum - (min * n) = 10

【讨论】:

    【解决方案3】:

    我已经用二分搜索解决了这个问题!

    def main():
    #codechef question SALARY 
    t = input()
    t = int(t)
    while t > 0:
        n = input()
        n = int(n)
        val = list(map(int, input().split(" ")))
        initial_sum = sum(val)
        min_value = min(val)
        left = 0
        right = 10000000000
        while left <= right:
            mid = (left + right) // 2
            may_be = initial_sum + (mid * (n-1))
            mean = may_be / n
            diff = mean - min_value
            if diff == mid:
                break
            elif diff < mid:
                right = mid - 1
            else:
                left = mid + 1
        print(mid)
        t -= 1
    

    如果 name == 'ma​​in': 主要()

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-07-18
      • 2022-10-23
      • 2021-03-27
      • 2012-11-09
      • 1970-01-01
      • 2015-01-08
      • 2021-05-24
      • 2017-12-01
      相关资源
      最近更新 更多