Алгоритмы поиска и сортировки на python

Помогите, пожалуйста, найти ошибку в коде. В последней строке выводит 2 6 5, а нужно 2 3 5 применял разные виды перестановки сортировки не получается пока.

Задача:

У пастуха есть n псов и m овец, причём i-й пёс характеризуется числом bi , а j-я овца характеризуется числом aj.

Пастух хочет отправить овец гулять под надзором псов. Овцу можно выпустить гулять только вместе с двумя псами-надсмотрщиками, причём если выбрана i-я овца вместе с j-м и k-м псами, то должны выполняться неравенства: bj < ai < bk.

Помогите пастуху выбрать наибольшее количество овец, которых можно отправить на прогулку за один раз.

Формат ввода:

Первая строка содержит два целых числа m и n (1 ≤ m, n ≤ 10^5). Вторая строка содержит m целых чисел a1,a2,…,am(0 ≤ ai ≤ 10^9) — характеристики овец. Третья строка содержит n целых чисел b1,b2,…,bn(0 ≤ bi≤ 10^9) — характеристики псов.

Формат вывода:

На первой строке выведите число s — максимальное количество овец, которых можно отправить на прогулку за один раз.

На следующих s строках выведите по три числа: номер овцы i, номер пса j, номер пса k. Должны выполняться неравенства bj < ai < bk.

Пример ввода:

4 6
2 3 4 5
1 3 2 2 5 2

Пример вывода:

2
1 1 2
2 3 5
from bisect import bisect_left, bisect_right


class AnimalGrouping:
    def __init__(self, sheep, dogs):
        # Сортируем овец и собак вместе с их исходными индексами
        self.sheep = sorted((value, index + 1) for index, value in enumerate(sheep))  # Овцы: (значение, индекс)
        self.dogs = sorted((value, index + 1) for index, value in enumerate(dogs))    # Псы: (значение, индекс)

    def find_max_sheep_with_dogs(self):
        # Результат — список из групп вида (овца, пёс1, пёс2)
        result = []
        dog_values = [value for value, _ in self.dogs]  # Отдельный список лишь для значений псов

        for sheep_value, sheep_index in self.sheep:
            # Находим первый индекс псов, у которых характеристика < овцы
            left_index = bisect_left(dog_values, sheep_value)
            # Находим первый индекс псов, у которых характеристика > овцы
            right_index = bisect_right(dog_values, sheep_value)

            # Проверяем, есть ли в списке псы, подходящие под условия
            if left_index > 0 and right_index < len(dog_values):
                # Получаем пару псов, которые подходят текущей овце
                left_dog_value, left_dog_index = self.dogs[left_index - 1]
                right_dog_value, right_dog_index = self.dogs[right_index]

                # Добавляем пару (номер овцы, номера двух псов) в результат
                result.append((sheep_index, left_dog_index, right_dog_index))

                # Удаляем использованных псов, чтобы их невозможно было использовать повторно
                del self.dogs[right_index]  # Удаление правого пса
                del dog_values[right_index]  # Обновление значений характеристик псов
                del self.dogs[left_index - 1]  # Удаление левого пса
                del dog_values[left_index - 1]  # Обновление значений характеристик псов

        return result


# Чтение входных данных
def main():
    m, n = list(map(int, input().split()))  # Количество овец и псов
    sheep = list(map(int, input().split()))  # Характеристики овец
    dogs = list(map(int, input().split()))  # Характеристики псов

    # Создаём объект AnimalGrouping
    grouping = AnimalGrouping(sheep, dogs)
    result = grouping.find_max_sheep_with_dogs()

    # Выводим количество групп
    print(len(result))  # Количество групп (овца, пёс1, пёс2)
    for group in result:
        print(*group)  # Сами группы


# Запускаем main() при выполнении скрипта
if __name__ == "__main__":
    main()                       

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

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

Ошибка в логике решения. Вам в комментариях написали пример, тут некорректный жадный алгоритм.

Пусть у нас есть овцы x,y и мы обоих можем выпустить. Тогда a < x < b c < y < d. Если b < c то мы можем заменить на a < x < b < c и b < c < y < d. Таким образом можно считать, то для всех овец любая левая собака меньше любой правой. Дальше если x < y, то, можно сделать что a < c b < d. Таким образом общая структура собак выглядит так (li - левая собака i овцы).

l1 l2 l3 ... lk <....> r1 r2 r3 ... rk

Где под <...> имеются в виду собаки которых не будет в ответе и которые ни на что не влияют. Уже есть решение за O (N log (N + M)). Сортируем с индексами овец, собак. Дальше бинарным поиском переберём ответ k. Первые k собак "левые", последние k собак "правые". Теперь как проверить что план корректный. Просто для каждой пары li, ri нужно найти овцу. Всегда можно брать самую маленькую по значению овцу из тех, которые ещё не использованы и больше нижней границы. Если она больше правой, то не получится сопоставить и нужно уменьшать k. Это можно удобно сделать скользящим окном (поддерживая первую потенциально подходящую овцу).

Осталось написать код.

→ Ссылка