Задание 1. Двоичный поиск

Во входном файле задан отсортированный массив чисел от 0 до 2 миллиардов. Сначала написано число N, размер массива. Потом выписаны N чисел.

Далее написано число K, за которым следует K чисел x_i, которые надо найти в массиве. Необходимо для каждого числа x_i вывести его индекс в массиве, это номер числа с начала массива, считая с 0. Например, в массиве [10, 20, 30] число 30 имеет индекс 2. Если число не найдено, нужно вывести -1. Если одинаковых чисел несколько, можно вывести любой индекс. Все ответы выводятся в отдельной строке.

Для решения задачи используйте следующий алгоритм. Заведите переменные left и right, которые хранят индексы диапазона поиска числа в массиве. Сначала left=0, right=LENGTH(A)-1. Т.е. мы ищем число от начала до конца массива. На каждом шаге проверяется значение в массиве по индексу ровно посередине между left и right: middle = (left + right)/2 Если оно больше искомого числа, значит, искомое число в левой половине, и нужно переназначить right = middle. Иначе, если оно больше искомого числа, оно в правой половине, и требуется переназначить: left = middle. Последний случай, число совпало с искомым, значит, индекс найден.

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

В этой программе очень важно правильно разобрать все граничные условия и случаи, иначе очень легко получить бесконечный цикл или неверно работающую программу. Постоянно помните о смысле переменных left и right, проверяйте, не меняется ли их смысл при присваивании. Попробуйте посмотреть, как изменится код, если заменить смысл right на правую границу диапазона поиска, но в которой точно нет значения. Сначала right=LENGTH(A), потом оно должно изменять так, что искомое значение находится от left (включительно) до right (не включительно).

Тесты: https://students.iposov.spb.ru/21spring/algs/binary-search/tests-bin-search.zip

Двоичный поиск по ответу

Теория: https://wiki.algocode.ru/index.php?title=%D0%91%D0%B8%D0%BD%D0%B0%D1%80%D0%BD%D1%8B%D0%B9%D0%BF%D0%BE%D0%B8%D1%81%D0%BA%D0%BF%D0%BE_%D0%BE%D1%82%D0%B2%D0%B5%D1%82%D1%83

На прямой дано $N$ точек и число $k$. Вы должны покрыть точки с помощью $k$ одинаковых по длине отрезков, причем требуется определить, какая минимальная длина отрезков подходит в задаче.

Например, если на прямой даны точки $A=10$, $B=15$, $C=30$, $D=40$ и $k=2$, то эти точки можно покрыть отрезками длины 10. Первый отрезок покрывает точки $A$ и $B$, второй — $C$ и $D$.

Если $k=3$, то эти же точки можно покрыть отрезками длины 5. Первый отрезок покрывает точки $A$ и $B$, второй — $C$, третий $D$.

При $k=4$ ответ будет 0. Каждый из четырех отрезков покрывает одну из точек.

Для решения задачи используйте двоичный поиск по ответу. Отрезок длины 0 это самое маленькое возможное значение, а отрезок длины от первой точки до последней — самое большое, такой один отрезок гарантированно покроет все точки.

В стандартном вводе в первой строке дано число $N$, во второй — $k$, далее даны $N$ чисел $0 \le A_i \le 2,000,000,000$. Точки $A_i$ расположены по возрастанию, сортировать массив не требуется.

Выведите в стандартный вывод одно число - минимальную длину отрезков.

Тесты: https://students.iposov.spb.ru/21spring/algs/binary-search/on-the-result/binary-search-on-the-result-tests.zip