Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- # Основная идея решения.
- #
- # Упорядочить элементы по возрастанию. Посчитать количество пар,
- # между которыми разность не больше чем, данная. Если количество
- # пар оказалось больше, чем k, то пробуем для меньшей разности,
- # если меньше, чем k, то делаем подсчёт для большей разности.
- # Используем двоичный поиск при этом.
- #
- # Подсчёт пар для заданной разности d основан на положении,
- # что если разность между крайними числами в промежутке равна d,
- # то и все пары в промежутке дают разность не превосходящую d.
- # Функция выдаёт количество различных пар, которые
- # могут дать d элементов.
- def count_diffs(d):
- return d / 2 * (d - 1)
- # Функция выдаёт количество различных пар в листе a,
- # дающих разности, не превосходящие целевую разность d.
- def count_list_diffs(a, d):
- count = l = r = r_prev = 0
- while r < len(a):
- # Находим стартовую (левую) позицию для следующего полуинтервала,
- # включающего пары, с разностью, не превышающей d.
- # В первой итерации внешнего цикла ни одна итерация этого
- # внутреннего цикла выполнена не будет.
- while a[r] - a[l] > d and l < r:
- l += 1
- # Сдвигаем правую границу до тех пор, пока полуинтервал
- # [l; r) не будет включать максимально возможное количество
- # пар, с разностью, не превосходящей d.
- while r < len(a) and a[r] - a[l] <= d:
- r += 1
- # Любая из пар на полуинтервале [l; r) даёт разность,
- # не превосходящую d.
- count += count_diffs(r - l)
- if r_prev - l > 1:
- # Если полуинтервал пересекается с предыдущим, то пары из
- # пересечения-полуинтервала [l; r_prev) учитываются
- # дважды при суммировании количеств. Необходимо вычесть
- # количество, которое даёт пересечение.
- count -= count_diffs(r_prev - l)
- # Сохраняем предыдущее значение r, чтобы потом учесть
- # возможное пересечение полуинтервалов.
- r_prev = r
- return count
- # Найти k-ю по величине разницу между элементами a.
- def get_kth(a, k):
- a.sort()
- hi = a[-1]
- lo = 0
- while hi > lo:
- mid = (hi + lo) // 2
- if count_list_diffs(a, mid) < k:
- # Если количество пар для разницы mid меньше k,
- # то целевая разность будет больше mid,
- # следовательно, нижнюю границу lo также
- # можно установить больше mid.
- lo = mid + 1
- else:
- hi = mid
- return lo
- input()
- a = [int(x) for x in input().split()]
- k = int(input())
- print(get_kth(a, k))
Add Comment
Please, Sign In to add comment