Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <bits/stdc++.h>
- #define MAXN 9
- #define ll long long
- using namespace std;
- //up, right, down, left
- int dx[4] = {-1,0,1,0};
- int dy[4] = {0,1,0,-1};
- struct cell{
- int x, y;
- cell(){}
- cell(int X, int Y): x(X), y(Y){}
- bool operator < (const cell &o) const{
- if(x == o.x){
- return y < o.y;
- }
- return x < o.x;
- }
- };
- vector<vector<vector<cell> > > polyminos(10);
- unordered_map<ll, bool> vis;
- const ll BASE = 33ll;
- const ll MOD = (ll) (10e9) + 7ll;
- ll myHash(vector<cell> &ref){
- ll ans = 0ll, P = 1ll;
- for(int i = 0; i < (int) ref.size(); i++){
- ans = ((((ref[i].x) * P) % MOD)+ans) % MOD;
- P *= BASE;
- ans = ((((ref[i].y) * P) % MOD)+ans) % MOD;
- P *= BASE;
- }
- return ans;
- }
- void generatePoly(const int LIM){
- polyminos[1].push_back(vector<cell> (1, cell(0,0)));
- for(int len = 2; len <= LIM; len++){
- for(auto i : polyminos[len-1]){
- //now iterating through the j-th polymino and generating new polymino
- for(auto j : i){
- int x = j.x, y = j.y;
- for(int k = 0; k < 4; k++){
- vector<cell> newPoly;
- int newX = x + dx[k];
- int newY = y + dy[k];
- if(newX < 0){
- for(auto cells : i){
- newPoly.push_back(cell(cells.x+1, cells.y));
- }
- newX++;
- }else if(newY < 0){
- for(auto cells : i){
- newPoly.push_back(cell(cells.x, cells.y+1));
- }
- newY++;
- }else{
- for(auto cells : i){
- newPoly.push_back(cell(cells.x, cells.y));
- }
- }
- bool can = 1;
- for(int i = 0; i < (int) newPoly.size() && can; i++){
- if(newPoly[i].x == newX && newPoly[i].y == newY){
- can = 0;
- }
- }
- if(can){
- newPoly.push_back(cell(newX, newY));
- sort(newPoly.begin(), newPoly.end());
- ll theHash = myHash(newPoly);
- if((int) newPoly.size() == len && !vis[theHash]){
- polyminos[len].push_back(newPoly);
- vis[theHash] = 1;
- }
- }else{
- newPoly.clear();
- }
- }
- }
- }
- }
- }
- int N,M;
- char grid[MAXN][MAXN];
- bool vis2[MAXN][MAXN];
- int cnt;
- vector<pair<int, int> > places;
- void dfs(int x, int y){
- if(grid[x][y] >= '0' && grid[x][y] <= '9'){
- cnt++;
- }
- vis2[x][y] = 1;
- for(int i = 0; i < 4; i++){
- int nx = x + dx[i];
- int ny = y + dy[i];
- if(nx >= 0 && ny >= 0 && nx < N && ny < M && !vis2[nx][ny] && (grid[nx][ny] == '.' || (grid[nx][ny] >= '0' && grid[nx][ny] <= '9'))){
- dfs(nx, ny);
- }
- }
- }
- int black, cntB;
- void dfs2(int x, int y){
- if(cntB > black) return;
- if(grid[x][y] == '#'){
- cntB++;
- }
- vis2[x][y] = 1;
- for(int i = 0; i < 4; i++){
- int nx = x + dx[i];
- int ny = y + dy[i];
- if(nx >= 0 && ny >= 0 && nx < N && ny < M && !vis2[nx][ny] && grid[nx][ny] == '#'){
- dfs2(nx, ny);
- }
- }
- }
- void dfs3(int x, int y){
- if(grid[x][y] != '.'){
- cntB++;
- }
- vis2[x][y] = 1;
- for(int i = 0; i < 4; i++){
- int nx = x + dx[i];
- int ny = y + dy[i];
- if(nx >= 0 && ny >= 0 && nx < N && ny < M && !vis2[nx][ny] && grid[nx][ny] == '#'){
- dfs3(nx, ny);
- }
- }
- }
- bool isOk(){
- int total = 0;
- memset(vis2, 0, sizeof(vis2));
- int L = -1, C = -1;
- for(int i = 0; i < N; i++){
- for(int j = 0; j < M; j++){
- if(grid[i][j] == '#'){
- L = i, C = j;
- }
- if(!vis2[i][j] && grid[i][j] != '#'){
- cnt = 0;
- dfs(i,j);
- if(cnt != 1){
- return 0;
- }
- total += cnt;
- }
- if(i > 0 && j > 0){
- if(grid[i][j] == '#' && grid[i-1][j] == '#' && grid[i][j-1] == '#' && grid[i-1][j-1] == '#'){
- return 0;
- }
- }
- }
- }
- cntB = 0;
- dfs2(L,C);
- return (total == (int) places.size()) && black == cntB;
- }
- bool canPlace(int x, int y, int dx_, int dy_, vector<cell> &poly){
- int cnt = 0;
- for(int i = 0; i < (int) poly.size(); i++){
- int nx = x + dx_ + poly[i].x;
- int ny = y + dy_ + poly[i].y;
- if(nx >= 0 && ny >= 0 && nx < N && ny < M){
- if(grid[nx][ny] == '.'){
- return 0;
- }else if(grid[nx][ny] >= '0' && grid[nx][ny] <= '9'){
- cnt++;
- }
- }else{
- return 0;
- }
- }
- return cnt == 1;
- }
- void add(int x, int y, int dx_, int dy_, vector<cell> &poly){
- for(int i = 0; i < (int) poly.size(); i++){
- int nx = x + dx_ + poly[i].x;
- int ny = y + dy_ + poly[i].y;
- if(!(grid[nx][ny] >= '0' && grid[nx][ny] <= '9')){
- grid[nx][ny] = '.';
- }
- }
- }
- void remove(int x, int y, int dx_, int dy_, vector<cell> &poly){
- for(int i = 0; i < (int) poly.size(); i++){
- int nx = x + dx_ + poly[i].x;
- int ny = y + dy_ + poly[i].y;
- if(!(grid[nx][ny] >= '0' && grid[nx][ny] <= '9')){
- grid[nx][ny] = '#';
- }
- }
- }
- bool foundSol;
- //checando se existe mais de 1 componente preto
- //se a contagem de caras que alcancei com o DFS != dos caras pretos, entao ja tem pelo menos 2 regioes desconexas
- bool isGood(int sum){
- if(sum == N*M - (int) places.size()){
- return 1;
- }
- for(int i = 0; i < N; i++){
- for(int j = 0; j < M; j++){
- if(grid[i][j] == '#'){
- memset(vis2, 0, sizeof(vis2));
- cntB = 0;
- dfs3(i,j);
- if(cntB < sum){
- return 0;
- }else{
- return 1;
- }
- }
- }
- }
- return 1;
- }
- //tentando colocar os componentes, sabendo a quantidade de caras pretos que ainda restam retirar
- void backTrack(int pos, int total){
- if(foundSol) return;
- if(pos == (int) places.size()){
- if(isOk()){
- for(int i = 0; i < N; i++){
- for(int j = 0; j < M; j++){
- printf("%c", grid[i][j]);
- }
- printf("\n");
- }
- foundSol = true;
- }
- }else{
- if(!isGood(total)){
- return;
- }
- int centerx = places[pos].first;
- int centery = places[pos].second;
- int len = grid[centerx][centery] - '0';
- for(auto polymino : polyminos[len]){
- for(auto cells : polymino){
- //using cell in (centerx, centery)
- int dx_ = centerx - (centerx + cells.x);
- int dy_ = centery - (centery + cells.y);
- if(canPlace(centerx, centery, dx_, dy_, polymino)){
- add(centerx, centery, dx_, dy_, polymino);
- backTrack(pos+1, total - (len - 1));
- remove(centerx, centery, dx_, dy_, polymino);
- }
- }
- }
- }
- }
- int main(){
- generatePoly(9);
- while(scanf("%d%d", &N, &M) && (N > 0 && M > 0)){
- places.clear();
- foundSol = 0;
- black = N*M;
- for(int i = 0; i < N; i++){
- for(int j = 0; j < M; j++){
- scanf(" %c", &grid[i][j]);
- if(grid[i][j] >= '0' && grid[i][j] <= '9'){
- places.push_back(make_pair(i,j));
- black -= (grid[i][j] - '0');
- }else{
- grid[i][j] = '#';
- }
- }
- }
- backTrack(0, N*M - (int) places.size());
- printf("\n");
- }
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement