Advertisement
Guest User

termites.cc

a guest
May 28th, 2014
289
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.53 KB | None | 0 0
  1. #include <iostream>
  2. #include <queue>
  3.  
  4. const int INFESTED = 0x80;
  5. const int PASSABLE = 0x08;
  6.  
  7. struct pos {
  8.   int x, y;
  9. };
  10.  
  11. struct Map {
  12.   int w, h;
  13.   pos source;
  14.   char grid[15][15];
  15.  
  16.   /* Safely get the tile at (X, Y). */
  17.   char get(int x, int y) const {
  18.     return (x >= 0 && x < w && y >= 0 && y < h) ? grid[x][y] : '\0';
  19.   }
  20.  
  21.   /* Returns true if the bunkers are currently safe. */
  22.   bool safe() {
  23.     std::queue<pos> queue{};
  24.     queue.push(source);
  25.     while (!queue.empty()) {
  26.       pos p = queue.front();
  27.       queue.pop();
  28.       char c = get(p.x, p.y);
  29.       if (c & PASSABLE && !(c & INFESTED)) {
  30.         if (c == 'o') {
  31.           clear();
  32.           return false;
  33.         } else {
  34.           grid[p.x][p.y] |= INFESTED;
  35.           queue.push(pos{p.x + 1, p.y + 0});
  36.           queue.push(pos{p.x - 1, p.y + 0});
  37.           queue.push(pos{p.x + 0, p.y + 1});
  38.           queue.push(pos{p.x + 0, p.y - 1});
  39.         }
  40.       }
  41.     }
  42.     clear();
  43.     return true;
  44.   }
  45.  
  46.   /* Attempt to solve the map for COUNT walls. */
  47.   bool solve(int count) {
  48.     if (count == 0) return safe();
  49.     for (int y = 0; y < h; y++) {
  50.       for (int x = 0; x < w; x++) {
  51.         if (grid[x][y] == '-') {
  52.           if ((get(x - 1, y + 0) != '-') ||
  53.               (get(x + 1, y + 0) != '-') ||
  54.               (get(x + 0, y + 1) != '-') ||
  55.               (get(x + 0, y - 1) != '-')) {
  56.             grid[x][y] = '@';
  57.             if (solve(count - 1)) {
  58.               return true;
  59.             } else {
  60.               grid[x][y] = '-';
  61.             }
  62.           }
  63.         }
  64.       }
  65.     }
  66.     return false;
  67.   }
  68.  
  69.   /* Remove all infestation markers. */
  70.   void clear() {
  71.     for (int y = 0; y < h; y++) {
  72.       for (int x = 0; x < w; x++) {
  73.         grid[x][y] &= ~INFESTED;
  74.       }
  75.     }
  76.   }
  77. };
  78.  
  79. std::istream &operator>>(std::istream &in, Map &map) {
  80.   in >> map.h >> map.w;
  81.   for (int y = 0; y < map.h; y++) {
  82.     for (int x = 0; x < map.w; x++) {
  83.       in >> map.grid[x][y];
  84.       if (map.grid[x][y] == '*') map.source = {x, y};
  85.     }
  86.   }
  87.   return in;
  88. }
  89.  
  90. std::ostream &operator<<(std::ostream &out, const Map map) {
  91.   for (int y = 0; y < map.h; y++) {
  92.     for (int x = 0; x < map.w; x++) {
  93.       out << map.grid[x][y];
  94.     }
  95.     out << std::endl;
  96.   }
  97.   return out;
  98. }
  99.  
  100. int main() {
  101.   Map map;
  102.   std::cin >> map;
  103.   int wallcount = -1;
  104.   do {
  105.     wallcount++;
  106.     std::cerr << "Trying " << wallcount << " walls ..." << std::endl;
  107.   } while (!map.solve(wallcount));
  108.   std::cout << wallcount << std::endl << map;
  109.   return 0;
  110. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement