题目描述:
由数字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 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
输入格式:
每组测试数据第一行一个整数n(1≤n≤30)
接下来n行,由0和1组成的n×n的方阵。
方阵内只有一个闭合圈,圈内至少有一个0。
输出格式:
已经填好数字2的完整方阵。
样例输入:
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
样例输出:
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
AC Code:
#include<bits/stdc++.h> using namespace std; #define N 50 int a[N][N];//转换地图的数组 int dx[]={0,0,-1,1};//两个方向数组 int dy[]={1,-1,0,0}; int n; void dfs(int x,int y) { a[x][y]=3;//把外部可以搜索到的0修改为3 for(int i=0;i<4;i++) {//四个方向搜索 int tx=x+dx[i]; int ty=y+dy[i]; if(tx>=1&&tx<=n&&ty>=1&&ty<=n&&a[tx][ty]==0) { //不越界,并且这个点是0 dfs(tx,ty);//继续下一个点的搜索 } } } int main() { scanf("%d",&n); for(int i=1;i<=n;i++) { for(int j=1;j<=n;j++) { scanf("%d",&a[i][j]);//地图全部都是0,1数字,所以直接开int整型数组就行 } } //从最外圈开始向内圈搜索 //最外圈由第一行、最后一行、第一列、最后一列构成 for(int i=1;i<=n;i++) {//搜索第一行和最后一行 if(a[1][i]==0) {//第一行共有m列 dfs(1,i); } if(a[n][i]==0) {//第n行,即最后一行共有m列 dfs(n,i); } } for(int j=1;j<=n;j++) {//搜索第一列和最后一列 if(a[j][1]==0) {//第一列共有n行 dfs(j,1); } if(a[j][n]==0) {//第m列,即最后一列共有n行 dfs(j,n); } } for(int i=1;i<=n;i++) { for(int j=1;j<=n;j++) { if(a[i][j]==0) { /*因为从最外圈开始搜索,每搜索一圈,都可以将外部未被包围的0修改为1, 而最终那些一直都是0,没有被修改过的点,就是被包围起来的数字2方阵*/ a[i][j]=2; } } } for(int i=1;i<=n;i++) { for(int j=1;j<=n;j++) { if(a[i][j]==3) { /*此时我们已经将外部可以搜索到的0全部修改为了3 而输出样例中被我们修改为3的点还要再修改为0*/ a[i][j]=0; } } } for(int i=1;i<=n;i++) {//所有工作完成,最后打印方阵 for(int j=1;j<=n;j++) { printf("%d ",a[i][j]); } printf("\n"); } return 0; }