第一次总结:填涂颜色

题目描述

由数字 00 组成的方阵中,有一任意形状闭合圈,闭合圈由数字 11 构成,围圈时只走上下左右 44 个方向。现要求把闭合圈内的所有空间都填写成 22。例如:6\times 66×6 的方阵(n=6n=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 \le n \le 30)n(1≤n≤30)。

接下来 nn 行,由 00 和 11 组成的 n \times nn×n 的方阵。

方阵内只有一个闭合圈,圈内至少有一个 00。

//感谢黄小U饮品指出本题数据和数据格式不一样. 已修改(输入格式)

输出格式

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

说明/提示

1<=n<=30

思路:0有两种情况,一种是在包围范围内,另外一种是在包围范围外,为了区别这两种,我们使用另外一个数组(brr)来进行存储判断的结果,在判断函数中,我们使用队列来依次弹出数组来进行判断,队列弹出的数暂先使用结构体来存储数据,弹出数据后,在进行上下左右的判断,满足条件我们就进行标记,不满足就进行下一个判断。(纯暴力搜索,我们只需要对数组中的数一个一个进行判断,一个一个标记就可以了)。

//我们使用一个数组来存储数据,一个数组存储判断结果
//如果数组中一个数等于0的同时,又存在上下左右有等于1的,该数就被包裹在内数
//打印时如果该数等于0的同时,判断数组等于1,就为包裹的数 
#include
using namespace std;
int n,arr[35][35]={0},brr[35][35]={0},tmep;
struct point{
	int x,y;
};
int dx[4]={0,0,-1,1},dy[4]={-1,1,0,0};//进行四周寻找,要确保相加等于0 
queue q;
void intput()
{
	brr[0][0]=1;
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
	for(int j=1;j<=n;j++)
	{
		scanf("%d",&tmep);
	if(tmep!=0)
	arr[i][j]=1;
	}
}	
void print()
{
	for(int i=1;i<=n;i++)
	{
	for(int j=1;j<=n;j++)
	{
		if(arr[i][j]==0&&brr[i][j]==0)//注意判断条件 
		printf("2 ");
		else if(arr[i][j]==1)
		printf("1 ");
		else
		printf("0 ");
	}	
	printf("\n");
	}
}
void judge()
{
	q.push(point{0,0});
	while(!q.empty())//将闭合区间外面的0全部标记为1 
	{
		point p=q.front();//找到队列中的队列的第一个元素 
		q.pop();//在不断进行删除第一个元素 
		for(int i=0;i<4;i++)
		{
			int x=p.x+dx[i];
			int y=p.y+dy[i];
			if(x<0||x>n+1||y<0||y>n+1)//越界情况 
			continue;
			if(arr[x][y]==0&&brr[x][y]==0)//为0且未被搜索过
			{
				brr[x][y]=1;
				q.push(point{x,y});
			}
		}
	}
}
int main()
{
	intput();
	judge();
	print();
    return 0;
}

你可能感兴趣的:(c++,算法,开发语言)