Bonetrousle | Найдите B различных положительных целых чисел ниже K, чтобы их сумма была равна N, или скажите, что это невозможно. | Ошибка тайм-аута

#algorithm

#алгоритм

Вопрос:

Я пытаюсь выполнить задачу Bonetrousle HackerRank.

Проблема заключается в следующем:

Найдите B различных положительных целых чисел ниже K, чтобы их сумма была равна N, или скажите, что это невозможно.

Ограничения:

 n, k <= 10^18
b <= 10^5
  

Вы можете проверить, что решение существует, если заданное N лежит между минимальной (возьмите первые B элементов) и максимальной (возьмите последние B элементов) возможной суммой.
С этого момента я начинаю с минимальной суммы и пытаюсь довести ее до N, присваивая каждому элементу максимально возможное значение без нарушения ограничения. (без дублирования, сумма == N)

Ниже приведен код, который я написал.

 def foo1(n,k,b):
    minSum = (b*(b 1))//2
    maxSum = (b)*(k-b 1 k)//2
    #maxSum = (k*(k 1))//2 - minSum
    #print(minSum, maxSum)


    if n>=minSum and n<=maxSum:
        minArr = [i for i in range(1,b 1)]
        minArr.reverse()
        sumA = sum(minArr)

        maxA = k
        for i in range(len(minArr)):
            tmp = minArr[i]
            minArr[i] = maxA
            sumA = sumA-tmp minArr[i]

            while sumA > n:
                sumA -=1
                minArr[i] -= 1
            maxA = minArr[i]-1
            """
            while sumA 1 <= n and minArr[i] 1 <= k and minArr[i] 1 != maxA:
                #print(minArr, maxA)

                minArr[i] =1
                sumA  =1
            maxA = minArr[i]    
            if sumA == n:
                break
            """

    else:
        return [-1]
    return minArr
  

Код выдает правильные решения, однако время ожидания для ранга хакера истекает для 4 тестовых случаев. (пример n, b, k : 19999651, 20000000, 6324)
Это дает ответ в течение 3 секунд на моей машине для того же тестового примера.

Изначально я думал, что проблема была в прокомментированном коде, поскольку я пытался увеличивать каждый элемент массива 1 на 1, пока не будет достигнута сумма. Я изменил код, чтобы присвоить каждому элементу максимально возможное значение, а затем уменьшить его, если это нарушает ограничения, однако, по-видимому, это не сильно помогло.

Есть предложения по изменению кода, чтобы заставить его пройти ограничение по времени или гораздо более быстрый алгоритм?

Ответ №1:

Сначала найдите B наибольших последовательных целых чисел с суммой <= N. Проблема невозможна, если эта последовательность начинается с целого числа < 1 или заканчивается целым числом > K

Сумма B целых чисел, начинающихся с x, равна B * (2x B-1) / 2, поэтому просто решайте для x напрямую.

Очевидно, что если бы вы добавили единицу к каждому из целых чисел в последовательности, начинающейся с x, то вы получили бы следующие B последовательных целых чисел, и их сумма равна > N, так что вам не нужно увеличивать так много. Просто добавьте 1 к целым числам с наибольшей N-суммой в последовательности, чтобы сумма получилась правильной.

Комментарии:

1. Есть доказательства для N - max_sum <= B ?

2. @PhamTrung Если N — sum >= B , то вам следовало выбрать большее x .