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;
}
}