Бинарный поиск по ответу. Задача на поиск максимальной длины

Есть n веревочек, нужно нарезать из них k кусков одинаковой длины. Найдите максимальную длину кусков, которые можно получить.

Входные данные В первой строке заданы два числа — n и k (1≤n,k≤10000 ). Далее в каждой из последующих n строк записано по одному числу — длине очередной веревочки ai (1≤ai≤107 ).

Выходные данные Выведите одно вещественное число — максимальную длину кусков, которые можно получить. Ответ будет считаться верным, если относительная или абсолютная погрешность не превышает 10−6 .

Пример

Входные данные

4 11
802
743
457
539

Выходные данные
200.5
n, k = map(int, input().split())
def bina_(sp,n,k): # поиск целого числа
    i = 0
    r = 10 ** 7 + 1
    while r > i + 1:
        sr = (i + r) // 2
        if proveri_(sr,sp,k) == 1:
            i = sr
        else:
            r = sr
    return i

def bina_s(sp,a,k): # поиск числа после точки
    i = 0
    r = 9999999999
    while r > i + 1:
        sr = (i + r) // 2
        if proveri_s(sp,a,k,sr) == 1:
            i = sr
        else:
            r = sr
    return i
def proveri_s(sp,a,k,sr):
    co_ = 0
    for i in sp:
        co_ += int(i // float(f'{a}.{sr}'))
    if co_ >= k:
        return 1

def proveri_(sr,sp,k):
    co_ = 0
    for i in sp:
        co_ += (i // sr)
    if co_ >= k:
        return 1

sp = []
for i in range(n):
    sp.append(int(input()))
    
a = bina_(sp,n,k)
b = bina_s(sp,a,k)
print(float(f'{a}.{b}'))

Упростил код

n, k = map(int, input().split())
def bina_(sp,n,k):
    i = 1
    r = 10 ** 7 + 1
    for _ in range(1000):
        sr = (i + r) / 2
        if proveri_(sr,sp,k) == 1:
            i = sr
        else:
            r = sr
    return i

def proveri_(sr,sp,k):
    co_ = 0
    for i in sp:
        co_ += (i // sr)
    if co_ >= k:
        return 1

sp = []
for i in range(n):
    sp.append(int(input()))

a = bina_(sp,n,k)
print(a)

Ответы (2 шт):

Автор решения: user27630724

Первый код не искал относительную или абсолютную погрешность не превышающую 10−6 Измененный код: относительную или абсолютную погрешность реализовал через for _ in range(100):

    i = 0
    r = 10 ** 7 + 1
    for _ in range(100):
        sr = (i + r) / 2
        if proveri_(sr,sp,k) == 1:
            i = sr
        else:
            r = sr
    return i

def proveri_(sr,sp,k):
    co_ = 0
    for i in sp:
        co_ += (i // sr)
    if co_ >= k:
        return 1


a = bina_(sp,n,k)
print(a)
→ Ссылка
Автор решения: MBo

Цикл бинарного поиска по условию должен работать, пока относительная или абсолютная погрешность не станет меньше или равной одной миллионной. А погрешность в данном случае - ширина оставшегося диапазона (делённая на верхнюю границу для относительной погрешности)

i = 0
r = 10 ** 7 + 1
while ((r-i)/r > 1E-6) and (r-i > 1E-6):
→ Ссылка