0 / 0 / 0
Регистрация: 03.01.2020
Сообщений: 5
|
||||||
Минимальная сумма растояний между точками27.01.2024, 22:45. Показов 2023. Ответов 16
Метки С++ для начинающих (Все метки)
Дано n точек на числовой прямой. Про каждую точку известна ее координата xi.
Расстоянием между точками с координатами x[i] и x[j] будем считать абсолютную разность их координат: abs(x[i] – x[j]). Точка с координатой x[j] находится ближе к точке x[i], чем точка x[k], если расстояние между точками x[i] и x[j] меньше, чем между x[i] и x[k]. Требуется выбрать из данных точек точку c наименьшей координатой такую, что сумма ее расстояний до ближайших к ней k точек наименьшая возможная. Формат входных данных В первой строке дано два натуральных числа n и k — число точек и число ближайших точек, которые надо учитывать (1 ≤ k < n ≤ 10^5). Во второй строке заданы n целых чисел xi — координаты точек (−10^9 ≤ xi ≤ 10^9). Формат выходных данных Выведите два числа — координату выбранной точки и сумму расстояний от нее до ближайших к ней k точек. пример 1 ввод 5 2 4 2 3 6 0 вывод 3 2 можно взять число 3, и считать расстояние до 4, тогда разность по модулю равна 1, вторым число 2, разность по модулю 1, в сумме получается 2 пример 2 10 2 4 4 19 2 14 9 11 9 3 20 вывод 4 1 можно взять точку 4, и считать расстояние до 4, тогда разность по модулю будет 0, и до 3 так разность по модулю будет 1, в сумме 2 вот, мой код, у меня неправильный ответ на втором примере
0
|
27.01.2024, 22:45 | |
Ответы с готовыми решениями:
16
Найти максимальное и минимальное значение между точками и вывести их вместе с точками Минимальная выпуклая оболочка (2D) с условием на расстояние между точками В треугольнике найти точку, сумма растояний от которой до вершин треугольника минимальна |
Вездепух
![]() ![]() ![]() 12873 / 6737 / 1810
Регистрация: 18.10.2014
Сообщений: 17,057
|
|
27.01.2024, 23:10 | |
Так а что тут реализовано7 Опишите подробно ваш подход к решению, то есть алгоритм.
Где у вас в коде определяются "ближайших к ней k точек"? Я что-то в упор этого не увидел. Я вижу какие-то циклы, назначение которых мне не понятно. Один цикл суммирует расстояния до k точек слева. Другой цикл суммирует расстояния до всех точек справа (то есть тут даже k никак не фигурирует). Что это такое? Что должны делать эти циклы?
0
|
Вездепух
![]() ![]() ![]() 12873 / 6737 / 1810
Регистрация: 18.10.2014
Сообщений: 17,057
|
|
27.01.2024, 23:43 | |
Задача, скорее всего, рассчитана на применение техники "скользящей окрестности". Точки предварительно сортируются по координатам. "Окрестность" - это набор k ближайших точек к текущей точке. При переходе к рассмотрению следующей точки: из "окрестности", возможно, уходит какая-то точка слева и, возможно, добавляется какая-то точка справа. Сумма расстояний при такой операции изменяется (можно пересчитать, но лучше догадаться как сделать без полного пересчета).
Проходим такой "окрестностью" весь массив - находим в итоге минимальную сумму расстояний. Так а где в коде сортировка вектора? Во-первых, что такое "i+k"? Где у вас у коде "сумма координат от него до i+k"? Дайте номера строк. Во-вторых, с чего вы это взяли, что "ближайшие точки" - это некое "i+k"? Где связь? "Ближайшие" - значит ближайшие по координатам. Они могут лежать как слева, так и справа от точки. Одновременно.
1
|
![]() |
||||||
28.01.2024, 00:08 | ||||||
Выводы примеров совпали. Вышло так.
2
|
Вездепух
![]() ![]() ![]() 12873 / 6737 / 1810
Регистрация: 18.10.2014
Сообщений: 17,057
|
|
28.01.2024, 01:07 | |
"Cуммой расстояний до ближайших k точек" для какой точки?
Более того, не ясно, зачем вообще понадобился такой цикл, если очевидно, что вычисляемая им сумма заведомо равна coordinates[i+k] - coordinates[i] ? И никакого цикла не нужно.Почему эти k точек будут являться "ближайшими k" для точки i + k / 2 ?Только потому, что примеры приведены для непоказательного случая k=2. "Сумма расстояний" - это сумма расстояний от точки до всех остальных точек, а не сумма попарных расстояний между соседями в группе. То есть ваш цикл вычисляет совсем не ту сумму вообще.
1
|
![]() |
|
28.01.2024, 01:09 | |
TheCalligrapher, я делал, чтобы прийти к результатам данных примеров
0
|
случайный прохожий
![]() 3170 / 2184 / 638
Регистрация: 20.07.2013
Сообщений: 5,848
|
|
28.01.2024, 02:31 | |
А как (быстро) сортировать такое количество точек (порядка 105)?
Процесс наверняка займет какое-то (возможно, критичное) время. Хотя ввод данных (вручную) тоже процесс не быстрый (если это влияет на результат).
1
|
Вездепух
![]() ![]() ![]() 12873 / 6737 / 1810
Регистрация: 18.10.2014
Сообщений: 17,057
|
||||||
28.01.2024, 10:12 | ||||||
Моя попытка реализовать именно то, о чем я вел речь в #4. Получилось эффективно, но в коде несколько более громоздко, чем я ожидал. Возможно что есть более простое решение
105 - это, вообще-то, детский сад. Сортировать обычным алгоритмом сортировки. Смысл задачи - найти способ избежать циклов длины k при обработке каждой из n точек. Если делать так, то будет вылет за ограничения по времени. И по сравнению с этой тормознёй сортировка 105 точек - это мелочи.
3
|
случайный прохожий
![]() 3170 / 2184 / 638
Регистрация: 20.07.2013
Сообщений: 5,848
|
|
28.01.2024, 19:52 | |
TheCalligrapher, позволю себе включить "режим старого деда".
Возьмем гипотетическую ситуацию - "простая" сортировка 105 элементов через двойной цикл требует примерно 1010 операций (сравнения), не считая "перестановку" элементов. Тогда "простая" (без оптимизации) проверка (всех) k соседних точек для n точек (для отсортированного массива) потребует примерно (если не ошибаюсь) n * (k + 1) операций (или n * k * (k + 1) ? - тогда вопрос снимается), то есть количество того же порядка (или на порядки больше ?). С оптимизацией кол-во будет меньше (но тут мне сложно посчитать). Для сортировки есть sort. Допустим, нет этой функции (или метода, название не имеет значения). Тогда нам пришлось бы и сортировку оптимизировать. То есть две эти части задачи (теоретически) также сравнимы (если нет разницы на порядки) по необходимости оптимизации. Я прав или несу полную чушь? И еще. В этой теме ничего не сказано про то, что 105 элементов - это много (касаемо памяти). При этом есть фраза Там это 106 элементов (момент, что в той задаче массив не нужен, опустим). Неужели разница настолько сильная (вроде всего 10-кратная)? Благодарю за внимание.
0
|
Нарушитель
![]() ![]() 4514 / 2400 / 987
Регистрация: 01.06.2021
Сообщений: 8,294
|
|
28.01.2024, 20:15 | |
Кто-нибудь знает, что за олимпиада: https://rsr-olymp.ru/upload/fi... -21-22.pdf ? Задание взято отсюда.
0
|
случайный прохожий
![]() 3170 / 2184 / 638
Регистрация: 20.07.2013
Сообщений: 5,848
|
|||||||||||
28.01.2024, 23:06 | |||||||||||
Royal_X, да хз.
Насчет решения задачи - у меня вроде "что-то" получилось (через функцию; дополнительно см. комментарии в коде). Насчет ошибок не знаю, проверял только на тестовых значениях. Но логика должна быть верна, если нигде не напортачил. Код:
1
|
Вездепух
![]() ![]() ![]() 12873 / 6737 / 1810
Регистрация: 18.10.2014
Сообщений: 17,057
|
||||||
30.01.2024, 05:07 | ||||||
Несколько другой подход: на основе другого классического приема - предварительное вычисление всех частичных сумм.
Заранее отсортируем массив координат, а затем заранее подготовим массив sums[] , который каждой точке i (индекс) сопоставляет сумму расстояний от нее до всех точек слева от нее (вплоть до самой левой). Такой массив легко строится инкрементально в один проход слева-направо. Тогда пользуясь этим массивом мы сможем мгновенно вычислять сумму расстояний sum_left(j, i) от точки i до точек слева от нее в диапазоне индексов [j, i] (j < i ):sum_left(j, i) := sums[i] - sums[j] - (xs[i] - xs[j]) * jА также, пользуясь этим же массивом, мы сможем мгновенно вычислять сумму расстояний sum_right(i, j) от точки i до точек справа от нее в диапазоне индексов [i, j] (j > i ):sum_right(i, j) := (xs[j] - xs[i]) * (j - i + 1) - sum_left(i, j)Пользуясь этими двумя функциями мы можем мгновенно вычислять сумму расстояний от любой точки i до ее соседей в диапазоне [il, il+k] . В остальном алгоритм остается тем же: последовательно анализируем точки массива и одновременно двигаем по массиву "окно" шириной в k+1 точек. После того, как мы увеличили индекс текущей точки i , нам может лишь понадобиться сдвинуть диапазон [il, il+k] вправо в поиске нового минимума.То есть в моей предыдущей реализации текущее значение суммы постоянно поддерживалось инкрементально, путем вычитания из суммы расстояния до уходящей из окрестности точки и добавления в сумму расстояния до приходящей в окрестность точки (а также, разумеется, сумму нужно было инкрементально обновлять и при увеличении индекса i ). В этой реализации мы, выполнив препроцессинг, имеем возможность просто мгновенно получать требуемую сумму для любой точки и любой окрестности, поэтому постоянная инкрементальная поддержка суммы становится ненужной
k , то есть выполнив такой препроцессинг один раз, задачу затем можно эффективно решать много раз на одних и тех же входных данных, но для разных значений k .
2
|
случайный прохожий
![]() 3170 / 2184 / 638
Регистрация: 20.07.2013
Сообщений: 5,848
|
||||||
30.01.2024, 09:59 | ||||||
Решение отличное.
И имеется следующая идея (возможно, бредовая). Если использовать не сумму расстояний до всех точек слева от x[i], а, например, сумму всех элементов слева от x[i] или (что, наверно, лучше) значения x[i] - x[i - 1] ? Как вариант данных (для понимания идеи):
0
|
случайный прохожий
![]() 3170 / 2184 / 638
Регистрация: 20.07.2013
Сообщений: 5,848
|
|
30.01.2024, 17:47 | |
Немного подумал и пришел к выводу, что способ решения через использование значений y[i] = x[i] - x[i - 1] является не очень оптимальным (про сумму всех элементов слева от x[i] вообще молчу - большой вопрос, как это вообще использовать). "Локально" (в статике) вариант (через y[i]) достаточно простой, но при движении по окрестности точки x[i] (не говоря уж про изменение точек x[i]) потребуется либо применять (полный) пересчет "сумм расстояний до точек окрестности", либо убирать левую точку с добавлением правой через кучу операций.
Так что идея оказалась совсем не жизнеспособной. А выглядело все весьма заманчиво... ![]() ![]()
0
|
Вездепух
![]() ![]() ![]() 12873 / 6737 / 1810
Регистрация: 18.10.2014
Сообщений: 17,057
|
|
31.01.2024, 00:06 | |
Я не вижу смысл в предварительном вычислении "дешевых" характеристик, вроде x[i] - x[i - 1]. Зачем это предварительно вычислять, если эта величина и так вычисляется мгновенно?
Если решение на основе таких тривиальных характеристик существует, то оно будет в первую опираться на какое-то пока мне неизвестное свойство задачи. Именно это свойство и надо искать. А x[i] - x[i - 1] тут ничего не меняет. Добавлено через 2 часа 53 минуты Как раз таки это можно использовать. В моем решении в #14 массив sum[] определяется какчто эквивалентно Вычитаемое - именно ваша сумма. Произведение x[j]*(j+1) вычисляется "мгновенно", то есть можно считать, что использованная мною сумма фактически эквивалентна предложенной вами.
1
|
31.01.2024, 00:06 | ||||||
Помогаю со студенческими работами здесь
17
Поставить точку D на оси Х так, чтобы сумма растояний от точек А, В, С была минимальной Минимальная сумма расстояний между каждым элементом массива и множествами из К-элементов этого массива Минимальная сумма расстояний между каждым элементом массива и множествами из к-элементов этого массива На плоскости заданы 2n точек. Объединить их в пары так, чтобы сумма всех расстояний между точками была миниальной Установить биекцию между точками эллипса и точками окружности Искать еще темы с ответами Или воспользуйтесь поиском по форуму:
|
|
Новые блоги и статьи
![]() |
||||
Работа с объемным DOM в javascript
Htext 04.04.2025
Сегодня прочитал статью тут о расходах памяти в JS, ее утечках и т. п. И вот что вспомнил из своей недавней практики. Может, кому пригодится. Хотя, в той статье об этом тоже есть.
Дело в том, что я. . .
|
Оптимизация производительности Node.js с помощью кластеризации
run.dev 04.04.2025
Масштабирование приложений для обработки тысяч и миллионов запросов — обыденная задача для многих команд. Node. js, благодаря своей асинхронной событийно-ориентированной архитектуре, стал популярной. . .
|
Управление зависимостями в Python с Poetry
py-thonny 04.04.2025
Стандартный инструмент для установки пакетов в Python - pip - прекрасно справляется с базовыми сценариями: установил пакет командой pip install и используешь его. Но что произойдёт, когда разные. . .
|
Мониторинг с Prometheus в PHP
Jason-Webb 04.04.2025
Prometheus выделяется среди других систем мониторинга своим подходом к сбору и хранению метрик. В отличие от New Relic, который использует агентный подход и отправляет данные во внешнее хранилище,. . .
|
Пакет Context в Golang: Управление потоками и ресурсами
golander 04.04.2025
Работа с горутинами в Go часто напоминает управление непослушными детьми - они разбегаются кто куда, делают что хотят и не всегда завершаются вовремя. К счастью, в Go 1. 7 появился пакет context,. . .
|
Контейнеризация React приложений с Docker
Reangularity 03.04.2025
Контейнеризация позволяет упаковать приложение со всеми его зависимостями в автономный контейнер, который можно запустить на любой платформе с установленным Docker. Это существенно упрощает процессы. . .
|
Свой попап в SwiftUI
mobDevWorks 03.04.2025
SwiftUI, как декларативный фреймворк от Apple, предоставляет множество инструментов для создания пользовательских интерфейсов. В нашем распоряжении есть такие API как alerts, popovers, action sheets. . .
|
Антипаттерны микросервисной архитектуры
ArchitectMsa 03.04.2025
Хорошо спроектированная микросервисная система может выдержать испытание временем, оставаясь гибкой, масштабируемой и устойчивой к большинству проблем. Такая архитектура обладает высоким уровнем. . .
|
std::mutex в C++: Советы и примеры использования
bytestream 03.04.2025
std::mutex - это механизм взаимного исключения, который гарантирует, что критический участок кода выполняется только одним потоком в каждый момент времени. Это простое, но могущественное средство. . .
|
Не удержался от оценки концепции двигателя Стирлинга.
Hrethgir 03.04.2025
Сколько не пытался - она выдавала правильные схемы, причём случайно рисовала горячие области в середине, холодные по краям, трубки с краёв в низ и магнит в соединяющей, но при этой выдавала описание. . .
|