Advertisement
Guest User

Untitled

a guest
Aug 22nd, 2016
673
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 8.36 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2. #define MAXN 9
  3. #define ll long long
  4. using namespace std;
  5.  
  6. //up, right, down, left
  7. int dx[4] = {-1,0,1,0};
  8. int dy[4] = {0,1,0,-1};
  9.  
  10. struct cell{
  11.     int x, y;
  12.     cell(){}
  13.     cell(int X, int Y): x(X), y(Y){}
  14.     bool operator < (const cell &o) const{
  15.         if(x == o.x){
  16.             return y < o.y;
  17.         }
  18.         return x < o.x;
  19.     }
  20. };
  21.  
  22. vector<vector<vector<cell> > > polyminos(10);
  23. unordered_map<ll, bool> vis;
  24.  
  25. const ll BASE = 33ll;
  26. const ll MOD = (ll) (10e9) + 7ll;
  27.  
  28. ll myHash(vector<cell> &ref){
  29.     ll ans = 0ll, P = 1ll;
  30.     for(int i = 0; i < (int) ref.size(); i++){
  31.         ans = ((((ref[i].x) * P) % MOD)+ans) % MOD;
  32.         P *= BASE;
  33.         ans = ((((ref[i].y) * P) % MOD)+ans) % MOD;
  34.         P *= BASE;
  35.     }
  36.     return ans;
  37. }
  38.  
  39. void generatePoly(const int LIM){
  40.     polyminos[1].push_back(vector<cell> (1, cell(0,0)));
  41.     for(int len = 2; len <= LIM; len++){
  42.         for(auto i : polyminos[len-1]){
  43.             //now iterating through the j-th polymino and generating new polymino
  44.             for(auto j : i){
  45.                 int x = j.x, y = j.y;
  46.                 for(int k = 0; k < 4; k++){
  47.                     vector<cell> newPoly;
  48.                     int newX = x + dx[k];
  49.                     int newY = y + dy[k];
  50.                     if(newX < 0){
  51.                         for(auto cells : i){
  52.                             newPoly.push_back(cell(cells.x+1, cells.y));
  53.                         }
  54.                         newX++;
  55.                     }else if(newY < 0){
  56.                         for(auto cells : i){
  57.                             newPoly.push_back(cell(cells.x, cells.y+1));
  58.                         }
  59.                         newY++;
  60.                     }else{
  61.                         for(auto cells : i){
  62.                             newPoly.push_back(cell(cells.x, cells.y));
  63.                         }
  64.                     }
  65.                     bool can = 1;
  66.                     for(int i = 0; i < (int) newPoly.size() && can; i++){
  67.                         if(newPoly[i].x == newX && newPoly[i].y == newY){
  68.                             can = 0;
  69.                         }
  70.                     }
  71.                     if(can){
  72.                         newPoly.push_back(cell(newX, newY));
  73.                         sort(newPoly.begin(), newPoly.end());
  74.                         ll theHash = myHash(newPoly);
  75.                         if((int) newPoly.size() == len && !vis[theHash]){
  76.                             polyminos[len].push_back(newPoly);
  77.                             vis[theHash] = 1;
  78.                         }
  79.                     }else{
  80.                         newPoly.clear();
  81.                     }
  82.                 }
  83.             }
  84.         }
  85.     }
  86. }
  87.  
  88. int N,M;
  89. char grid[MAXN][MAXN];
  90. bool vis2[MAXN][MAXN];
  91.  
  92. int cnt;
  93.  
  94. vector<pair<int, int> > places;
  95.  
  96. void dfs(int x, int y){
  97.     if(grid[x][y] >= '0' && grid[x][y] <= '9'){
  98.         cnt++;
  99.     }
  100.     vis2[x][y] = 1;
  101.     for(int i = 0; i < 4; i++){
  102.         int nx = x + dx[i];
  103.         int ny = y + dy[i];
  104.         if(nx >= 0 && ny >= 0 && nx < N && ny < M && !vis2[nx][ny] && (grid[nx][ny] == '.' || (grid[nx][ny] >= '0' && grid[nx][ny] <= '9'))){
  105.             dfs(nx, ny);
  106.         }
  107.     }
  108. }
  109.  
  110. int black, cntB;
  111.  
  112. void dfs2(int x, int y){
  113.     if(cntB > black) return;
  114.     if(grid[x][y] == '#'){
  115.         cntB++;
  116.     }
  117.     vis2[x][y] = 1;
  118.     for(int i = 0; i < 4; i++){
  119.         int nx = x + dx[i];
  120.         int ny = y + dy[i];
  121.         if(nx >= 0 && ny >= 0 && nx < N && ny < M && !vis2[nx][ny] && grid[nx][ny] == '#'){
  122.             dfs2(nx, ny);
  123.         }
  124.     }
  125. }
  126.  
  127. void dfs3(int x, int y){
  128.     if(grid[x][y] != '.'){
  129.         cntB++;
  130.     }
  131.     vis2[x][y] = 1;
  132.     for(int i = 0; i < 4; i++){
  133.         int nx = x + dx[i];
  134.         int ny = y + dy[i];
  135.         if(nx >= 0 && ny >= 0 && nx < N && ny < M && !vis2[nx][ny] && grid[nx][ny] == '#'){
  136.             dfs3(nx, ny);
  137.         }
  138.     }
  139. }
  140.  
  141. bool isOk(){
  142.     int total = 0;
  143.     memset(vis2, 0, sizeof(vis2));
  144.     int L = -1, C = -1;
  145.     for(int i = 0; i < N; i++){
  146.         for(int j = 0; j < M; j++){
  147.             if(grid[i][j] == '#'){
  148.                 L = i, C = j;
  149.             }
  150.             if(!vis2[i][j] && grid[i][j] != '#'){
  151.                 cnt = 0;
  152.                 dfs(i,j);
  153.                 if(cnt != 1){
  154.                     return 0;
  155.                 }
  156.                 total += cnt;
  157.             }
  158.             if(i > 0 && j > 0){
  159.                 if(grid[i][j] == '#' && grid[i-1][j] == '#' && grid[i][j-1] == '#' && grid[i-1][j-1] == '#'){
  160.                     return 0;
  161.                 }
  162.             }
  163.         }
  164.     }
  165.     cntB = 0;
  166.     dfs2(L,C);
  167.     return (total == (int) places.size()) && black == cntB;
  168. }
  169.  
  170. bool canPlace(int x, int y, int dx_, int dy_, vector<cell> &poly){
  171.     int cnt = 0;
  172.     for(int i = 0; i < (int) poly.size(); i++){
  173.         int nx = x + dx_ + poly[i].x;
  174.         int ny = y + dy_ + poly[i].y;
  175.         if(nx >= 0 && ny >= 0 && nx < N && ny < M){
  176.             if(grid[nx][ny] == '.'){
  177.                 return 0;
  178.             }else if(grid[nx][ny] >= '0' && grid[nx][ny] <= '9'){
  179.                 cnt++;
  180.             }
  181.         }else{
  182.             return 0;
  183.         }
  184.     }
  185.     return cnt == 1;
  186. }
  187.  
  188. void add(int x, int y, int dx_, int dy_, vector<cell> &poly){
  189.     for(int i = 0; i < (int) poly.size(); i++){
  190.         int nx = x + dx_ + poly[i].x;
  191.         int ny = y + dy_ + poly[i].y;
  192.         if(!(grid[nx][ny] >= '0' && grid[nx][ny] <= '9')){
  193.             grid[nx][ny] = '.';                
  194.         }
  195.     }
  196. }
  197.  
  198. void remove(int x, int y, int dx_, int dy_, vector<cell> &poly){
  199.     for(int i = 0; i < (int) poly.size(); i++){
  200.         int nx = x + dx_ + poly[i].x;
  201.         int ny = y + dy_ + poly[i].y;
  202.         if(!(grid[nx][ny] >= '0' && grid[nx][ny] <= '9')){
  203.             grid[nx][ny] = '#';                
  204.         }
  205.     }
  206. }
  207.  
  208. bool foundSol;
  209.  
  210. //checando se existe mais de 1 componente preto
  211. //se a contagem de caras que alcancei com o DFS != dos caras pretos, entao ja tem pelo menos 2 regioes desconexas
  212. bool isGood(int sum){
  213.     if(sum == N*M - (int) places.size()){
  214.         return 1;
  215.     }
  216.     for(int i = 0; i < N; i++){
  217.         for(int j = 0; j < M; j++){
  218.             if(grid[i][j] == '#'){
  219.                 memset(vis2, 0, sizeof(vis2));
  220.                 cntB = 0;
  221.                 dfs3(i,j);
  222.                 if(cntB < sum){
  223.                     return 0;
  224.                 }else{
  225.                     return 1;
  226.                 }
  227.             }
  228.         }
  229.     }
  230.     return 1;
  231. }
  232.  
  233.  
  234. //tentando colocar os  componentes, sabendo a quantidade de caras pretos que ainda restam retirar
  235. void backTrack(int pos, int total){
  236.     if(foundSol) return;
  237.     if(pos == (int) places.size()){
  238.         if(isOk()){
  239.             for(int i = 0; i < N; i++){
  240.                 for(int j = 0; j < M; j++){
  241.                     printf("%c", grid[i][j]);
  242.                 }
  243.                 printf("\n");
  244.             }
  245.             foundSol = true;
  246.         }
  247.     }else{
  248.         if(!isGood(total)){
  249.             return;
  250.         }
  251.         int centerx = places[pos].first;
  252.         int centery = places[pos].second;
  253.         int len = grid[centerx][centery] - '0';
  254.         for(auto polymino : polyminos[len]){
  255.             for(auto cells : polymino){
  256.                 //using cell in (centerx, centery)
  257.                 int dx_ = centerx - (centerx + cells.x);
  258.                 int dy_ = centery - (centery + cells.y);
  259.                 if(canPlace(centerx, centery, dx_, dy_, polymino)){
  260.                     add(centerx, centery, dx_, dy_, polymino);
  261.                     backTrack(pos+1, total - (len - 1));
  262.                     remove(centerx, centery, dx_, dy_, polymino);
  263.                 }
  264.             }
  265.         }
  266.     }
  267.    
  268. }
  269.  
  270. int main(){
  271.     generatePoly(9);
  272.     while(scanf("%d%d", &N, &M) && (N > 0 && M > 0)){
  273.         places.clear();
  274.         foundSol = 0;
  275.         black = N*M;
  276.         for(int i = 0; i < N; i++){
  277.             for(int j = 0; j < M; j++){
  278.                 scanf(" %c", &grid[i][j]);
  279.                 if(grid[i][j] >= '0' && grid[i][j] <= '9'){
  280.                     places.push_back(make_pair(i,j));
  281.                     black -= (grid[i][j] - '0');
  282.                 }else{
  283.                     grid[i][j] = '#';
  284.                 }
  285.             }
  286.         }
  287.         backTrack(0, N*M - (int) places.size());
  288.         printf("\n");
  289.     }
  290.     return 0;
  291. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement