填涂颜色广搜算法c语言,洛谷 P1162 填涂颜色

题目:填涂颜色

题目描述

由数字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

说明/提示

1≤n≤30

这道题乍一看比较难,实际想想其实也就是flood-fill。

考虑:什么是严格意义上“闭合”的?

如果对于一个联通块,它不“挨着”边缘,便可以判定它是“闭合的”。

那么我们可以将边缘上的所有位置进行广搜,碰到1便停止扩展了,被扩展的位置标记,最后没有被标记的位置即为所求!

代码如下:

#include

#include

#include

#include

#include

#include

#define pa pair

#define maxn 100

using namespace std;

const int dx[4] = {-1 , 1 , 0 , 0};

const int dy[4] = {0 , 0 , -1 , 1};

bool book[maxn][maxn];

int n , map[maxn][maxn];

bool valid(pa rec) {

if(rec.first < 0 || rec.first > n - 1 || rec.second < 0 || rec.second > n - 1) return false;

if(book[rec.first][rec.second] || map[rec.first][rec.second]) return false;

return true;

}

void bfs()

{

queue Q;

while(!Q.empty()) Q.pop();

if(map[0][0] == false) Q.push(make_pair(0 , 0));

if(map[0][n - 1] == false) Q.push(make_pair(0 , n - 1));

if(map[n - 1][0] == false) Q.push(make_pair(n - 1 , 0));

if(map[n - 1][n - 1] == false) Q.push(make_pair(n - 1 , n - 1));

for(int i = 1; i < n - 1; ++ i)

{

if(map[0][i] == false) Q.push(make_pair(0 , i));

if(map[i][0] == false) Q.push(make_pair(i , 0));

if(map[n - 1][i] == false) Q.push(make_pair(n - 1 , i));

if(map[i][n - 1] == false) Q.push(make_pair(i , n - 1));

}

while(!Q.empty())

{

pa now = Q.front() , next;

Q.pop();

for(int i = 0; i < 4; ++ i)

{

next = make_pair(now.first + dx[i] , now.second + dy[i]);

if(!valid(next)) continue;

book[next.first][next.second] = true;

Q.push(next);

}

}

return;

}

int main()

{

scanf("%d" , &n);

for(int i = 0; i < n; ++ i)

for(int j = 0; j < n; ++ j)

scanf("%1d" , &map[i][j]);

memset(book , 0 , sizeof(book));

bfs();

for(int i = 0; i < n; ++ i)

{

for(int j = 0; j < n; ++ j)

{

if(map[i][j] == 1) printf("1 ");

else if(book[i][j]) printf("0 ");

else printf("2 ");

}

puts("");

}

puts("");

return 0;

}

来源:https://www.cnblogs.com/zach20040914/p/12814401.html

你可能感兴趣的:(填涂颜色广搜算法c语言)