Advertisement
giGii

my_solution_stations

May 5th, 2023
803
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.65 KB | None | 0 0
  1. #include <algorithm>
  2. #include <cmath>
  3. #include <iostream>
  4. #include <unordered_map>
  5. #include <map>
  6. #include <string>
  7. #include <vector>
  8. #include <set>
  9.  
  10. using namespace std;
  11.  
  12. class RouteManager {
  13. public:
  14.     void AddRoute(int start, int finish) {
  15.         reachable_lists_[start][finish];
  16.         reachable_lists_[finish][start];
  17.  
  18.         // от любой станции до нее же можно добраться если не двигаться
  19.         reachable_lists_[start][start];
  20.         reachable_lists_[finish][finish];
  21.     }
  22.  
  23.     int FindNearestFinish(int start, int finish) const {
  24.         int result = abs(start - finish); // расстояние от текущего места до finish всегда как вариант будет, просто остался на месте и все
  25.         if (reachable_lists_.count(start) < 1) { // если станции start не существует, то понятное дело остаешься на месте и вот он ответ
  26.             return result;
  27.         }
  28.  
  29.         // если станция start есть, значит из нее можно куда-то ездить
  30.         const auto& reachable_stations = reachable_lists_.at(start);
  31.  
  32.         // алгоритм найдет ближайшую большую или равную finish
  33.         auto station = reachable_stations.lower_bound(finish);
  34.        
  35.         // ни одной больше или равной станиции, чем станция finish нет, значит finish дальше последней станции
  36.         if (station == reachable_stations.end()) {
  37.             // .   .    .  . A . . . . ....       B
  38.             //                             ^
  39.             return finish - (*(--reachable_stations.end())).first; // приблизиться можно к B, придя в последнюю
  40.         } else if ((*station).first == finish) { // finish достигается из start -- 0 по условию
  41.             return 0;
  42.         } else if (station != reachable_stations.begin()) {
  43.             // если найденная станция не первая в списке станций, значит можно посмотреть станцию ДО
  44.             // теперь можно оценить, от какой станции: station или before_station ближе до finish
  45.             const auto before_station = --station;
  46.             return std::min(result, std::min(abs(finish - (*station).first), abs(finish - (*before_station).first)));
  47.         }
  48.  
  49.         // если ничто другое, значит найденная станция это reachable_stations.begin()
  50.         // B .     ..  .    .     . A .. . .  . .  .  .. .
  51.         //   ^
  52.  
  53.         return abs(finish - (*station).first);
  54.  
  55.     }
  56.  
  57. private:
  58.     // unordered_map, чтобы на O(1) забирать внутренню мапу
  59.     // внутренний map, чтобы было отсортировано для lower_bound и итераторы на begin и end брались за O(1), а не как у set за log(N)
  60.     unordered_map<int, map<int, int>> reachable_lists_;
  61. };
  62.  
  63. int main() {
  64.     RouteManager routes;
  65.  
  66.     int query_count;
  67.     cin >> query_count;
  68.  
  69.     for (int query_id = 0; query_id < query_count; ++query_id) {
  70.         string query_type;
  71.         cin >> query_type;
  72.         int start, finish;
  73.         cin >> start >> finish;
  74.         if (query_type == "ADD"s) {
  75.             routes.AddRoute(start, finish);
  76.         } else if (query_type == "GO"s) {
  77.             cout << routes.FindNearestFinish(start, finish) << "\n"s;
  78.         }
  79.     }
  80. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement