top of page
Поиск

CodinGame | Defibrillators | C++

  • Bezukh
  • 20 июн. 2019 г.
  • 2 мин. чтения

Обновлено: 29 сент. 2024 г.

Приветствую! В C++ есть класс string. И, пока не возникает потребность как-то поделить на части длинную строку, всё в порядке. Те, кто знаком с Python, сразу же начинают искать аналоги .split, всякие инструменты для работы со срезами. Но, к сожалению, найти такие же очевидные и простые приёмы не получится. На примере задачи Defibrillators мы разберём простейшие методы работы со строками в C++.


Описание задачи:

В городе Монпелье на улицах можно встретить дефибрилляторы. Данные, соответствующие положению всех дефибрилляторов, доступны онлайн. Напишите программу, которая позволит пользователям находить дефибриллятор, ближайший к их местоположению, с помощью своего мобильного телефона.


Техническое описание задачи: Необходимые входные данные для программы предоставляются в текстовом формате. Каждая строка представляет собой описание дефибриллятора. Каждое описание дефибриллятора представлено следующими полями:

  • Уникальный ID дефибриллятора;

  • Название места;

  • Адрес;

  • Контактный телефон;

  • Долгота (градусы);

  • Широта (градусы).

Эти поля разделяются точкой с запятой (;). Внимание: десятичные числа в качестве разделителя используют запятую (,).

  Расстояние между двумя точками A и B рассчитывается по следующей формуле:

Формула
Примечание: 6371 соответствует радиусу Земли в км.

Программа должна отобразить название ближайшего места с дефибриллятором.


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

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

Недавние посты

Смотреть все
CodinGame | Расстояние Чебышёва, Lumen | C++

Приветствую! В этой небольшой заметке расскажу о расстоянии Чебышёва. Рассмотрим применение формулы для нахождения этого расстояния в...

 
 
 
CodinGame | There is no Spoon - Episode 1 | C++

Приветствую! В этой интересной задачке мы посмотрим на пример применения перегрузки операторов. Описание задачи: Игра ведётся на...

 
 
 
CodinGame | Brackets, extreme edition | C++

Приветствую! Вы наверняка сталкивались со всякими разными контейнерами. Например с очередями и односвязными списками. В задаче, которую...

 
 
 

Comments


© 2019-2024 by Bezukh Vladimir

bottom of page