CodinGame | Defibrillators | C++
- Bezukh
- 20 июн. 2019 г.
- 2 мин. чтения
Обновлено: 29 сент. 2024 г.
Приветствую! В C++ есть класс string. И, пока не возникает потребность как-то поделить на части длинную строку, всё в порядке. Те, кто знаком с Python, сразу же начинают искать аналоги .split, всякие инструменты для работы со срезами. Но, к сожалению, найти такие же очевидные и простые приёмы не получится. На примере задачи Defibrillators мы разберём простейшие методы работы со строками в C++.
Описание задачи:
В городе Монпелье на улицах можно встретить дефибрилляторы. Данные, соответствующие положению всех дефибрилляторов, доступны онлайн. Напишите программу, которая позволит пользователям находить дефибриллятор, ближайший к их местоположению, с помощью своего мобильного телефона.
Техническое описание задачи: Необходимые входные данные для программы предоставляются в текстовом формате. Каждая строка представляет собой описание дефибриллятора. Каждое описание дефибриллятора представлено следующими полями:
Уникальный ID дефибриллятора;
Название места;
Адрес;
Контактный телефон;
Долгота (градусы);
Широта (градусы).
Эти поля разделяются точкой с запятой (;). Внимание: десятичные числа в качестве разделителя используют запятую (,).
Расстояние между двумя точками A и B рассчитывается по следующей формуле:

Программа должна отобразить название ближайшего места с дефибриллятором.
Входные данные:
1 строка: пользовательская долгота.
2 строка: пользовательская широта.
3 строка: N локаций с дефибриллятором.
Следующие N строк: строка-описание дефибриллятора.
Выходные данные:
Название места с ближайшим дефибриллятором.
Пример:
Входные данные:
3,879483
43,608177
3
1;Maison de la Prevention Sante;6 rue Maguelone 340000 Montpellier;;3,87952263361082;43,6071285339217
2;Hotel de Ville;1 place Georges Freche 34267 Montpellier;;3,89652239197876;43,5987299452849
3;Zoo de Lunaret;50 avenue Agropolis 34090 Mtp;;3,87388031141133;43,6395872778854
Выходные данные:
Maison de la Prevention Sante
Defibrillators решение на C++:
Задача может показаться сложной. Разные строчки, что-то надо с ними делать. Ну, допустим, мы сможем разбить входные данные, но как будем их хранить? В массивах (векторах) имён/адресов/id? Вариант так себе. Сразу становится понятно, что очень неудобно поддерживать такое большое количество переменных. Лучшим решением станет создание своего типа данных.
Назовём нашу структуру Address. Текущая сущность, с который мы работаем, не представляет из себя чего-то сложного, поэтому мы используем семантическое (смысловое) обозначение struct (не class). Также это означает, что все поля по умолчанию публичные, работать с ними можно напрямую.
В нашей структуре определим следующие поля:
целочисленное ID;
вещественные долгота и широта;
строковые имя, адрес и телефон.
Далее определен конструктор структуры Address. Это нужно для того, чтобы компилятор имел какое-то представление о том, как правильно создавать объект этой структуры.
NUMBER_OF_LOCATIONS — количество локаций с дефибрилляторами;
Вектор адресов ADDRESESS типа Address для хранения входных данных;
USER_LONGITUDE и USER_LATITUDE — местоположение пользователя;
RADIUS_OF_THE_EARTH — радиус Земли.
Создадим отдельную функцию для считывания данных. В первую очередь получим местоположение пользователя, заменив с помощью replace() запятую на точку. Это нужно для того, чтобы с помощью stof() (string to float) корректно преобразовать строку к вещественному числу.
Считаем данные из потока cin с помощью getline() и разложим всё по полочкам. Вместо push_back лучше использовать emplace_back (если есть такая возможность).
Обратите внимание: данный код создаёт объект структуры Address. Именно для этого и нужно было описать конструктор.
С помощью простейшей функции найдём ближайший дефибриллятор. DBL_MAX — константа из библиотеки <cfloat>. Для работы cos() и sqrt() нужно подключить библиотеку <cmath>. Также воспользуемся range-based циклом. Обязательно используем ссылку, чтобы не создавать копии объектов! Мы не собираемся изменять сами адреса, поэтому используем константную ссылку.
Итоговый код:
Послесловие:
Порешать задачи по программированию можно на CodinGame. -- © Bezukh Vladimir, 2019
Comments