【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('\n')
#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\n",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;
	}
}
posted @ 2021-02-04 09:41  sigongzi  阅读(495)  评论(0编辑  收藏  举报