Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <algorithm>
- #include <cmath>
- #include <iostream>
- #include <unordered_map>
- #include <map>
- #include <string>
- #include <vector>
- #include <set>
- using namespace std;
- class RouteManager {
- public:
- void AddRoute(int start, int finish) {
- reachable_lists_[start][finish];
- reachable_lists_[finish][start];
- // от любой станции до нее же можно добраться если не двигаться
- reachable_lists_[start][start];
- reachable_lists_[finish][finish];
- }
- int FindNearestFinish(int start, int finish) const {
- int result = abs(start - finish); // расстояние от текущего места до finish всегда как вариант будет, просто остался на месте и все
- if (reachable_lists_.count(start) < 1) { // если станции start не существует, то понятное дело остаешься на месте и вот он ответ
- return result;
- }
- // если станция start есть, значит из нее можно куда-то ездить
- const auto& reachable_stations = reachable_lists_.at(start);
- // алгоритм найдет ближайшую большую или равную finish
- auto station = reachable_stations.lower_bound(finish);
- // ни одной больше или равной станиции, чем станция finish нет, значит finish дальше последней станции
- if (station == reachable_stations.end()) {
- // . . . . A . . . . .... B
- // ^
- return finish - (*(--reachable_stations.end())).first; // приблизиться можно к B, придя в последнюю
- } else if ((*station).first == finish) { // finish достигается из start -- 0 по условию
- return 0;
- } else if (station != reachable_stations.begin()) {
- // если найденная станция не первая в списке станций, значит можно посмотреть станцию ДО
- // теперь можно оценить, от какой станции: station или before_station ближе до finish
- const auto before_station = --station;
- return std::min(result, std::min(abs(finish - (*station).first), abs(finish - (*before_station).first)));
- }
- // если ничто другое, значит найденная станция это reachable_stations.begin()
- // B . .. . . . A .. . . . . . .. .
- // ^
- return abs(finish - (*station).first);
- }
- private:
- // unordered_map, чтобы на O(1) забирать внутренню мапу
- // внутренний map, чтобы было отсортировано для lower_bound и итераторы на begin и end брались за O(1), а не как у set за log(N)
- unordered_map<int, map<int, int>> reachable_lists_;
- };
- int main() {
- RouteManager routes;
- int query_count;
- cin >> query_count;
- for (int query_id = 0; query_id < query_count; ++query_id) {
- string query_type;
- cin >> query_type;
- int start, finish;
- cin >> start >> finish;
- if (query_type == "ADD"s) {
- routes.AddRoute(start, finish);
- } else if (query_type == "GO"s) {
- cout << routes.FindNearestFinish(start, finish) << "\n"s;
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement