洛谷P1162 填涂颜色(DFS漫水填充法)
题目描述
由数字 0组成的方阵中,有一任意形状闭合圈,闭合圈由数字 1 构成,围圈时只走上下左右 4 个方向。现要求把闭合圈内的所有空间都填写成 2 .例如:6×6 的方阵( n=6 ),涂色前和涂色后的方阵如下:
0 0 0 0 0 0 0 0 1 1 1 1 0 1 1 0 0 1 1 1 0 0 0 1 1 0 0 0 0 1 1 1 1 1 1 10 0 0 0 0 0 0 0 1 1 1 1 0 1 1 2 2 1 1 1 2 2 2 1 1 2 2 2 2 1 1 1 1 1 1 1
输入格式
每组测试数据第一行一个整数 n(1 \le n \le 30)n(1≤n≤30)
接下来 nn 行,由 00 和 11 组成的 n \times nn×n 的方阵。
方阵内只有一个闭合圈,圈内至少有一个 00 。
//感谢黄小U饮品指出本题数据和数据格式不一样. 已修改(输入格式)
输出格式
已经填好数字 2 的完整方阵。
输入样例#1
6 0 0 0 0 0 0 0 0 1 1 1 1 0 1 1 0 0 1 1 1 0 0 0 1 1 0 0 0 0 1 1 1 1 1 1 1
输出样例#1
0 0 0 0 0 0 0 0 1 1 1 1 0 1 1 2 2 1 1 1 2 2 2 1 1 2 2 2 2 1 1 1 1 1 1 1
说明
1<=n<=30
思路
在方阵内只有一个闭合圈,也就意味着除了被包围的那些0连通块,其余0连通块都与方阵边界有接触,
先对所有0连通块floodfill预先涂色,每个不同的值为0的连通块都被替换成-1,-2,-3...如下图
再遍历边界,找出并标记与边界有接触的0连通块
int temp[maxN];
memset(temp,0,sizeof(temp));
for(int i=1;i<=n;i++)
{
if(maze[1][i]<0)
{
temp[-maze[1][i]]=1;
}
}
for(int i=1;i<=n;i++)
{
if(maze[i][1]<0)
{
temp[-maze[i][1]]=1;
}
}
for(int i=1;i<=n;i++)
{
if(maze[n][i]<0)
{
temp[-maze[n][i]]=1;
}
}
for(int i=1;i<=n;i++)
{
if(maze[i][n]<0)
{
temp[-maze[i][n]]=1;
}
}
最后输出时判断是否是边界上的0,又是否是1即可
代码
#include<bits/stdc++.h>
using namespace std;
const int maxN=35;
int maze[maxN][maxN];
int book[maxN][maxN];
int tX,tY;
int n;
/*void Move(int x)
{
if(x==1) { tX=x+1;tY=y; }
if(x==2) { tX=x-1;tY=y; }
if(x==3) { tX=x;tY=y+1; }
if(x==4) { tX=x;tY=y-1; }
}*/
void DFS(int x,int y,int color)
{
maze[x][y]=color;
for(int k=1;k<=4;k++)
{
if(k==1) { tX=x+1;tY=y; }
if(k==2) { tX=x-1;tY=y; }
if(k==3) { tX=x;tY=y+1; }
if(k==4) { tX=x;tY=y-1; }
if(tX<1||tX>n||tY<1||tY>n) continue;
if(maze[tX][tY]==0&&book[tX][tY]==0)
{
book[tX][tY]=1;
DFS(tX,tY,color);
}
}
return;
}
int main()
{
int num=0;
memset(maze,0,sizeof(maze));
memset(book,0,sizeof(book));
scanf("%d",&n);
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
scanf("%d",&maze[i][j]);
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
if(maze[i][j]==0)
{
num--;
book[i][j]=1;
DFS(i,j,num);
}
}
}
printf("变为\n");
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
printf("%3d",maze[i][j]);
}
printf("\n");
}
int temp[maxN];
memset(temp,0,sizeof(temp));
for(int i=1;i<=n;i++)
{
if(maze[1][i]<0)
{
temp[-maze[1][i]]=1;
}
}
for(int i=1;i<=n;i++)
{
if(maze[i][1]<0)
{
temp[-maze[i][1]]=1;
}
}
for(int i=1;i<=n;i++)
{
if(maze[n][i]<0)
{
temp[-maze[n][i]]=1;
}
}
for(int i=1;i<=n;i++)
{
if(maze[i][n]<0)
{
temp[-maze[i][n]]=1;
}
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
if(maze[i][j]==1)
{
printf("1");
if(j!=n) printf(" ");
}
else if(temp[-maze[i][j]]==1)
{
printf("0");
if(j!=n) printf(" ");
}
else
{
printf("2");
if(j!=n) printf(" ");
}
}
printf("\n");
}
return 0;
}