coloriot

HA_61_Moves

Aug 2nd, 2025
151
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.36 KB | None | 0 0
  1. #include <iostream>
  2. #include <vector>
  3. #include <map>
  4. #include <utility>
  5.  
  6. using namespace std;
  7.  
  8. struct Coord {
  9.     int x;
  10.     int y;
  11.     bool operator<(const Coord& other) const {
  12.         if (x != other.x) return x < other.x;
  13.         return y < other.y;
  14.     }
  15. };
  16.  
  17. // Элемент пути: координата и ход,
  18. // который привёл сюда (для начальной — '\0')
  19. struct Step {
  20.     Coord pos;
  21.     char move;
  22. };
  23.  
  24. class PathSimplifier {
  25. public:
  26.     static vector<char> removeLoops(const vector<char>& moves) {
  27.         vector<Step> path; // текущий путь с учётом сохранения немедленных обратных
  28.         map<Coord, int> last_occurrence; // последняя позиция этой координаты в path
  29.  
  30.         Coord curr{0, 0};
  31.         path.push_back(Step{curr, '\0'});
  32.         last_occurrence[curr] = 0;
  33.  
  34.         for (char mv : moves) {
  35.             Coord next = applyMove(curr, mv);
  36.  
  37.             auto it = last_occurrence.find(next);
  38.             bool is_immediate_reverse = false;
  39.             if (!path.empty() && path.size() >= 2) {
  40.                 // предыдущая позиция перед curr
  41.                 Coord prev = path[path.size() - 2].pos;
  42.                 if (next.x == prev.x && next.y == prev.y) {
  43.                     is_immediate_reverse = true;
  44.                 }
  45.             }
  46.  
  47.             if (it != last_occurrence.end() && !is_immediate_reverse) {
  48.                 int prev_idx = it->second;
  49.                 // Если повторное вхождение не является
  50.                 // немедленным возвратом и это не просто next == curr
  51.                 if (prev_idx != (int)path.size() - 2) {
  52.                     // Длинная петля: обрезаем всё после prev_idx
  53.                     for (int i = (int)path.size() - 1; i > prev_idx; --i) {
  54.                         last_occurrence.erase(path[i].pos);
  55.                         path.pop_back();
  56.                     }
  57.                     // curr становится next (уже в path[prev_idx]); не добавляем mv
  58.                     curr = next;
  59.                     continue;
  60.                 }
  61.             }
  62.  
  63.             // Обычный шаг или немедленный обратный — добавляем
  64.             path.push_back(Step{next, mv});
  65.             last_occurrence[next] = (int)path.size() - 1;
  66.             curr = next;
  67.         }
  68.  
  69.         vector<char> result;
  70.         for (size_t i = 1; i < path.size(); ++i) {
  71.             result.push_back(path[i].move);
  72.         }
  73.         return result;
  74.     }
  75.  
  76. private:
  77.     static Coord applyMove(const Coord& c, char mv) {
  78.         Coord res = c;
  79.         switch (mv) {
  80.             case 'U': res.y += 1; break;
  81.             case 'D': res.y -= 1; break;
  82.             case 'L': res.x -= 1; break;
  83.             case 'R': res.x += 1; break;
  84.             default: break;
  85.         }
  86.         return res;
  87.     }
  88. };
  89.  
  90. int main() {
  91.     vector<char> moves = {'D','R','D','R','R','U','L','L','U','R','L','R'};
  92.     vector<char> simplified = PathSimplifier::removeLoops(moves);
  93.  
  94.     cout << "Array: ";
  95.     for (char c : moves) cout << c << ' ';
  96.     cout << "\nWithout loops: ";
  97.     for (char c : simplified) cout << c << ' ';
  98.     cout << "\n";
  99.     return 0;
  100. }
Advertisement
Add Comment
Please, Sign In to add comment