Advertisement
cmiN

150 div2 III

Mar 15th, 2012
160
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.04 KB | None | 0 0
  1. #include <iostream>
  2. #include <string>
  3. #include <vector>
  4. #include <set>
  5. using namespace std;
  6.  
  7.  
  8. class Ball {
  9.  
  10.     private:
  11.     typedef pair<int, int> pii_t;
  12.     typedef pair<int, pii_t> pip_t;
  13.     typedef set<pip_t> sp_t;
  14.     int bounceTime; // total moving time
  15.     sp_t path; // check for loops
  16.     int lin, col; // position of the ball
  17.     int addL, addC; // modifiers
  18.     bool loop; // loop switch
  19.     int destroyed; // destroyed bricks
  20.     vector<vector<int> > mat; // the map
  21.    
  22.     void bounce()
  23.     {
  24.         /// Change direction of the ball.
  25.         // Ox hit
  26.         if (!(col % 2)) {
  27.             if (addC == 1) addC = -1;
  28.             else addC = 1;
  29.         }
  30.         // Oy hit
  31.         if (!(lin % 2)) {
  32.             if (addL == 1) addL = -1;
  33.             else addL = 1;
  34.         }
  35.     }
  36.    
  37.     void update_path()
  38.     {
  39.         /// Update path in order to find loops.
  40.         int dir = addL * 10 + addC; // direction
  41.         pip_t item;
  42.         item.first = dir;
  43.         item.second.first = lin;
  44.         item.second.second = col;
  45.         pair<sp_t::iterator, bool> ret = path.insert(item);
  46.         if (!ret.second) {
  47.             // already there
  48.             loop = true;
  49.         }
  50.     }
  51.    
  52.     pii_t get_crd()
  53.     {
  54.         pii_t ret;
  55.         ret.first = lin / 2;
  56.         ret.second = col / 2;
  57.         if (addL == -1 && lin % 2 == 0) --ret.first;
  58.         if (addC == -1 && col % 2 == 0) --ret.second;
  59.         return ret;
  60.     }
  61.    
  62.     public:
  63.     Ball(vector<vector<int> >& mat)
  64.     {
  65.         this->mat = mat;
  66.         lin = 2;
  67.         col = 3;
  68.         addL = addC = 1;
  69.         bounceTime = 0;
  70.         loop = false;
  71.         destroyed = 0;
  72.     }
  73.    
  74.     void advance()
  75.     {
  76.         // next position
  77.         lin += addL;
  78.         col += addC;
  79.         //cerr << lin << " " << col << endl;
  80.         pii_t ret = get_crd();
  81.         int tmpL = ret.first, tmpC = ret.second;
  82.         if (mat[tmpL][tmpC] == 2) { // brick
  83.             // destroy it
  84.             mat[tmpL][tmpC] = 1;
  85.             ++destroyed;
  86.             path.clear();
  87.             bounce();
  88.         } else if (mat[tmpL][tmpC] == 0) { // block
  89.             bounce();
  90.         } // nothing if empty space
  91.         ++bounceTime;
  92.         update_path();
  93.     }
  94.    
  95.     bool in_loop() const
  96.     {
  97.         return loop;
  98.     }
  99.    
  100.     int get_destroyed() const
  101.     {
  102.         return destroyed;
  103.     }
  104.    
  105.     int get_time() const
  106.     {
  107.         return bounceTime;
  108.     }
  109.    
  110.     void show_map()
  111.     {
  112.         /// Debugging purposes.
  113.         for (int i = 0; i < mat.size(); ++i) {
  114.             for (int j = 0; j < mat.size(); ++j) {
  115.                 cout << mat[i][j];
  116.             }
  117.             cout << endl;
  118.         }
  119.     }
  120. };
  121.  
  122.  
  123. struct BrickByBrick {
  124.    
  125.     int bricks;
  126.     vector<vector<int> > mat;
  127.    
  128.     inline int decode(char arg)
  129.     {
  130.         switch (arg) {
  131.             case '#': return 0; // block
  132.             case '.': return 1; // space
  133.             case 'B': return 2; // brick
  134.         }
  135.         return -1;
  136.     }
  137.    
  138.     int timeToClear(vector<string> mat)
  139.     {
  140.         bricks = 0;
  141.         this->mat.resize(mat.size() + 2);
  142.         this->mat[0].resize(mat[0].size() + 2);
  143.         this->mat[mat.size() + 1].resize(mat[0].size() + 2);
  144.         for (int i = 1; i <= mat.size(); ++i) {
  145.             this->mat[i].resize(mat[0].size() + 2);
  146.             for (int j = 1; j <= mat[0].size(); ++j) {
  147.                 int obj = decode(mat[i - 1][j - 1]);
  148.                 this->mat[i][j] = obj;
  149.                 if (obj == 2) ++bricks;
  150.             }
  151.         }
  152.         Ball ball(this->mat);
  153.         //ball.show_map();
  154.         while (!(ball.in_loop() || ball.get_destroyed() == bricks)) ball.advance();
  155.         if (ball.in_loop()) return -1;
  156.         return ball.get_time();
  157.     }
  158. };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement