jw910731

Crazy.cpp

Mar 12th, 2022 (edited)
617
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.30 KB | None | 0 0
  1. #include <iostream>
  2. #include <vector>
  3. #include <string>
  4. #include <tuple>
  5.  
  6. /*
  7.  * w => y, h => x, row = grow y, map[x][y]
  8.  */
  9.  
  10. class Robot;
  11. std::ostream &operator<<(std::ostream &os, Robot r);
  12.  
  13. class Maze{
  14. private:
  15.     const int w, h;
  16.     std::vector<std::string> map;
  17.  
  18. public:
  19.     Maze(const int w, const int h):w(w),h(h){}
  20.     void insert_row(const std::string &row){
  21.         map.emplace_back(row);
  22.     }
  23.     inline bool check_available(const int x, const int y) const {
  24.         return x >= 0 && x < h && y >= 0 && y < w && map[x][y] != '#';
  25.     }
  26.     std::pair<int, int> findRobot(){
  27.         for(int i = 0 ; i < h ; ++i){ // x
  28.             for(int j = 0 ; j < w ; ++j){ // y
  29.                 if(map[i][j] == 'O'){
  30.                     return std::make_pair(i, j);
  31.                 }
  32.             }
  33.         }
  34.         return std::make_pair(0, 0);
  35.     }
  36.  
  37.     friend std::ostream &operator<<(std::ostream &os, Robot r);
  38. };
  39.  
  40. class Robot{
  41. private:
  42.     int x, y, d=0;
  43.     std::vector<std::tuple<int, int, int>> past;
  44.     const static int movement[][2];
  45.  
  46.     int is_walked() const {
  47.         for(auto &[xp, yp, dp] : past){
  48.             if(xp == x && yp == y && dp == d) return true;
  49.         }
  50.         return false;
  51.     }
  52.  
  53.     void rotate(){
  54.         d = (d+1)%4;
  55.     }
  56.  
  57.     void forward(){
  58.         x += movement[d][0];
  59.         y += movement[d][1];
  60.     }
  61.  
  62.     std::pair<int, int> futurePosition() const {
  63.         return std::make_pair(x + movement[d][0], y + movement[d][1]);
  64.     }
  65.  
  66. public:
  67.     Maze maze;
  68.     Robot(const int w, const int h):maze(w, h){}
  69.     void run(const int time){
  70.         for(int i = 0 ; i < time ; ++i){
  71.             std::cerr << x << ' ' << y << ' ' << d << '\n';
  72.             std::cerr << *this << '\n';
  73.             // walk
  74.             if(!is_walked()){
  75.                 int fx, fy;
  76.                 std::tie(fx, fy) = futurePosition();
  77.                 while(!maze.check_available(fx, fy)){
  78.                     rotate();
  79.                     std::tie(fx, fy) = futurePosition();
  80.                 }
  81.                 past.emplace_back(x, y, d);
  82.                 forward();
  83.             }
  84.             else{ // jump loop
  85.                 int lp; // loop index
  86.                 for(lp = int(past.size()); lp >= 0 ; --lp){
  87.                     auto [_x, _y, _d] = past[lp];
  88.                     if(_x == x && _y == y && _d == d){
  89.                         break;
  90.                     }
  91.                 }
  92.                 const int loop_size = int(past.size()) - lp;
  93.                 const int remain = time - i;
  94.                 const int state = (int(past.size() - loop_size)) + (remain % loop_size);
  95.                 std::tie(x, y, d) = past[state];
  96.                 i = time; // break
  97.             }
  98.         }
  99.     }
  100.  
  101.     void init(){
  102.         std::tie(x, y) = maze.findRobot();
  103.     }
  104.  
  105.     const std::pair<int, int> getPosition() const{
  106.         return std::make_pair(x, y);
  107.     }
  108.  
  109.     friend std::ostream &operator<<(std::ostream &os, Robot r);
  110. };
  111.  
  112. const int Robot::movement[][2] = {{-1, 0}, {0, 1}, {1, 0}, {0, -1}};
  113.  
  114. std::ostream &operator<<(std::ostream &os, Robot r){
  115.     for(int i = 0 ; i < int(r.maze.map.size()) ; ++i){
  116.         for(int j = 0 ; j < int(r.maze.map[i].size()) ; ++j){
  117.             if(i == r.x && j == r.y){
  118.                 os << 'O';
  119.             }
  120.             else{
  121.                 if(r.maze.map[i][j] == 'O'){
  122.                     os << '.';
  123.                 }
  124.                 else{
  125.                     os << r.maze.map[i][j];
  126.                 }
  127.             }
  128.         }
  129.         os << '\n';
  130.     }
  131.     return os;
  132. }
  133.  
  134.  
  135. int main(){
  136.     int w, h;
  137.     std:: cin >> w >> h; std::cin.ignore();
  138.     long long n;
  139.     std::cin >> n; std::cin.ignore();
  140.  
  141.     Robot robot(w, h);
  142.  
  143.     for (int i = 0; i < h; i++) {
  144.         std::string line;
  145.         getline(std::cin, line);
  146.         robot.maze.insert_row(line);
  147.     }
  148.     robot.init();
  149.     robot.run(n);
  150.     auto [x, y] = robot.getPosition();
  151.     std::cout << y << ' ' << x << '\n';
  152.     std::cerr << robot << '\n';
  153.     return 0;
  154. }
Add Comment
Please, Sign In to add comment