zoukankan      html  css  js  c++  java
  • 【Codeforces Gym】2020-2021 ACM-ICPC, Asia Seoul Regional Contest K. Tiling Polyomino

    K题想出来,VP的时候没写完,太屑了

    我们考虑把上下为空或左右为空的地方作为一个管子,剩下的地方作为块

    我们从一个大小大于1的块开始dfs,这必然构成了一个树结构,我们给每个非根节点分配一个管子,管子的方向决定了这个块是横着填满还是竖着填满,为什么大小为1的不行,因为大小为1的块(也就是一个类似拐点的地方)必须分配一个管子

    但是还有一些坑,可能把管子扒掉后,一些块出现了内部点度为1的凸起,会影响填充,我们只要按照这个块约定好的填充方向,把凸起部分填充方向的部分全都塞进这个块里

    举个例子

    6
    110011
    111011
    001001
    001011
    001110
    001110

    为了方便看出,我们把一个块改成8

    6
    110011
    111011
    001001
    001088
    008880
    008880

    假如这一块是根,然后我们还约好竖着填(根什么方向都无所谓),显然(4,6)的块会对我们产生阻碍

    我们只要把和(4,6)竖着相连的块都改成8就行

    6
    110018
    111018
    001008
    001088
    008880
    008880

    这样就填完了

    #include <bits/stdc++.h>
    #define fi first
    #define se second
    #define mo 99994711
    //#define ivorysi
    #define enter putchar('
    ')
    #define space putchar(' ')
    #define pii pair<int,int>
    typedef long long int64;
    using namespace std;
     
    template<class T>
    void read(T &res) {
    	res = 0;T f = 1;char c = getchar();
    	while(c < '0' || c > '9') {
    		if(c == '-') f = -1;
    		c = getchar();
    	}
    	while(c >= '0' && c <= '9') {
    		res = res * 10 + c - '0';
    		c = getchar();
    	}
    	res *= f;
    }
    template<class T>
    void out(T x) {
    	if(x < 0) {x = -x;putchar('-');}
    	if(x >= 10) out(x / 10);
    	putchar('0' + x % 10);
    }
     
    int N;
    int a[1005][1005],ans[1005][1005],cor[1005][1005],col;
    int dir[1005][1005],pol[1005][1005],siz[1000005],fildir[1000006];
    bool vis[1005][1005];
    int dx[] = {1,-1,0,0};
    int dy[] = {0,0,-1,1};
    char s[1005];
    void dfs(int x,int y) {
    	cor[x][y] = col;
    	siz[col]++;
    	for(int d = 0 ; d < 4 ; ++d){
    		int tx = x + dx[d],ty = y + dy[d];
    		if(a[tx][ty] && !pol[tx][ty] && !cor[tx][ty]) dfs(tx,ty);
    	}
    }
    void dfs1(int x,int y) {
    	vis[x][y] = 1;
    	for(int d = 0 ; d < 4 ; ++d) {
    		int tx = x + dx[d],ty = y + dy[d];
    		if(vis[tx][ty]) continue;
    		if(a[tx][ty]) {
    			if(pol[x][y] && !pol[tx][ty]) {
    				int c = cor[tx][ty];
    				fildir[c] = dir[x][y];
    				if(dir[x][y] == 0) {
    					int t = x;
    					while(pol[t][y]) {
    						cor[t][y] = c;
    						t -= dx[d];
    					}
    				}
    				else {
    					int t = y;
    					while(pol[x][t]) {
    						cor[x][t] = c;
    						t -= dy[d];
    					}
    				}
    			}
    			dfs1(tx,ty);
    		}
    	}
    }
    int main() {
    #ifdef ivorysi
    	freopen("f1.in","r",stdin);
    #endif
    	read(N);
    	for(int i = 1 ; i <= N ; ++i) {
    		scanf("%s",s + 1);
    		for(int j = 1 ; j <= N ; ++j) {
    			a[i][j] = s[j] - '0';
    		}
    	}
    	for(int i = 1 ; i <= N ; ++i) {
    		for(int j = 1 ; j <= N ; ++j) {
    			if(!a[i][j]) continue;
    			int cnt0 = 0,cnt1 = 0;
    			for(int d = 0 ; d < 2 ; ++d) {
    				int tx = i + dx[d],ty = j + dy[d];
    				if(tx >= 1 && tx <= N && ty >= 1 && ty <= N && a[tx][ty]) {
    					++cnt0;
    				}
    			}
    			for(int d = 2 ; d < 4 ; ++d) {
    				int tx = i + dx[d],ty = j + dy[d];
    				if(tx >= 1 && tx <= N && ty >= 1 && ty <= N && a[tx][ty]) {
    					++cnt1;
    				}
    			}
    			if(cnt0 + cnt1 == 2 && cnt0 != 1) {
    				pol[i][j] = 1;
    				if(cnt0 == 2) dir[i][j] = 0;
    				else dir[i][j] = 1;
    			}
    		}
    	}
    	int rt = 1;
    	for(int i = 1 ; i <= N ; ++i) {
    		for(int j = 1 ; j <= N ; ++j) {
    			if(a[i][j] &&  !pol[i][j] && !cor[i][j]) {
    				++col;
    				dfs(i,j);
    				if(siz[col] > 1) rt = col;
    			}
    		}
    	}
    	/*for(int i = 1 ; i <= N ; ++i) {
    		for(int j = 1 ; j <= N; ++j) {
    			out(cor[i][j]);
    		}
    		enter;
    	}*/
    	fildir[rt] = 1;
    	for(int i = 1 ; i <= N ; ++i) {
    		bool f = 0;
    		for(int j = 1 ; j <= N ; ++j) {
    			if(cor[i][j] == rt) {
    				dfs1(i,j);
    				f = 1;
    				break;
    			}
    		}
    		if(f) break;
    	}
    	/*for(int i = 1 ; i <= N ; ++i) {
    		for(int j = 1 ; j <= N; ++j) {
    			out(cor[i][j]);
    		}
    		enter;
    	}*/
    	for(int i = 1 ; i <= N ; ++i) {
    		for(int j = 1 ; j <= N ; ++j) {
    			if(cor[i][j] && !pol[i][j] && siz[cor[i][j]] > 1) {
    				int cnt = 0;
    				for(int d = fildir[cor[i][j]] * 2 ; d < (fildir[cor[i][j]] + 1) * 2 ; ++d) {
    					int tx = i + dx[d],ty = j + dy[d];
    					if(tx >= 1 && tx <= N && ty >= 1 && ty <= N && cor[tx][ty] == cor[i][j]) {
    						++cnt;
    					}
    				}
    				if(cnt == 0) {
    					for(int d = fildir[cor[i][j]] * 2 ; d < (fildir[cor[i][j]] + 1) * 2 ; ++d) {
    						int tx = i + dx[d],ty = j + dy[d];
    						while(a[tx][ty]) {
    							cor[tx][ty] = cor[i][j];
    							tx += dx[d];ty += dy[d];
    						}
    					}
    				}
    			}
    		}
    	}
    	/*for(int i = 1 ; i <= N ; ++i) {
    		for(int j = 1 ; j <= N; ++j) {
    			out(cor[i][j]);
    		}
    		enter;
    	}*/
    	/*for(int i = 1 ; i <= col ; ++i) {
    		printf("%d %d
    ",i,fildir[i]);
    	}*/
    	for(int j = 1 ; j <= N ; ++j) {
    		for(int i = 1 ; i <= N ; ++i) {
    			if(cor[i][j] && fildir[cor[i][j]] == 0) {
    				int t = i;
    				while(cor[t + 1][j] == cor[i][j]) ++t;
    				int s = i;
    				if((t - s + 1) & 1) {
    					ans[s][j] = ans[s + 1][j] = ans[s + 2][j] = 5;
    					s = s + 3;
    				}
    				for(int h = s ; h <= t ; ++h) ans[h][j] = 3;
    				i = t;
    			}
    		}
    	}
    	for(int i = 1 ; i <= N ; ++i) {
    		for(int j = 1 ; j <= N ; ++j) {
    			if(cor[i][j] && fildir[cor[i][j]] == 1) {
    				int t = j;
    				while(cor[i][t + 1] == cor[i][j]) ++t;
    				int s = j;
    				if((t - s + 1) & 1) {
    					ans[i][s] = ans[i][s + 1] = ans[i][s + 2] = 4;
    					s = s + 3;
    				}
    				for(int h = s ; h <= t ; ++h) ans[i][h] = 2;
    				j = t;
    			}
    		}
    	}
    	for(int i = 1 ; i <= N ; ++i) {
    		for(int j = 1 ; j <= N ; ++j) {
    			out(ans[i][j]);
    		}
    		enter;
    	}
    }
    
  • 相关阅读:
    中英文对照 —— 宗教
    十万个为什么 —— 冷知识
    十万个为什么 —— 冷知识
    OpenCV调试利器——Image Watch插件的安装和使用
    matlab 读写其他格式数据文件(excel)
    matlab 读写其他格式数据文件(excel)
    文学创作的艺术手法
    文学创作的艺术手法
    常用cl命令参数解释
    网站的栏目和目录结构规划方法
  • 原文地址:https://www.cnblogs.com/ivorysi/p/14370891.html
Copyright © 2011-2022 走看看