抠图|计蒜客2019蓝桥杯省赛 B 组模拟赛(一)




样例输入:
3
4 5
1 0 0 0 1
1 0 1 0 1
1 0 1 0 1
1 0 0 0 1
5 6
1 1 1 1 1 1
1 0 1 0 1 1
1 0 1 0 1 1
1 0 0 0 1 1
1 1 1 1 1 1
10 10
1 1 1 1 1 1 1 1 1 1
1 0 0 0 0 0 1 0 1 0
1 0 0 0 0 0 1 0 1 0
1 0 0 1 0 0 1 0 0 0
1 0 0 0 0 0 1 1 1 1
1 0 0 0 0 0 1 1 1 1
1 1 1 1 1 1 1 1 1 1
1 1 1 0 0 0 1 0 0 0
1 1 1 0 1 0 1 0 1 0
1 1 1 0 0 0 1 0 0 0

样例输出:
0 0 0 0 0
0 0 1 0 0
0 0 1 0 0
0 0 0 0 0
0 0 0 0 0 0
0 0 0 0 0 0
0 0 0 0 0 0
0 0 0 0 0 0
0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 1 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 1 0 0 0 1 0
0 0 0 0 0 0 0 0 0 0

思路:找连通分量,置1为0,可以用dfs 或者bfs。首先将4个边界为1的点加入搜索,将与该搜索点相连的1全部置为0。

代码一:dfs

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int INF = 0x3f3f3f3f;
const LL mod = 1e9 + 7;
const int N = 505;
int a[N][N];
int dx[4] = {0, 0, 1, -1};
int dy[4] = {1, -1, 0, 0};

int n, m;
bool isvalid(int x,int y){
	if(x <1 || x>n || y <1 || y> m) return false;
	return true;
}

//dfs搜索同一连通分量下的 1 
void dfs(int x,int y){
	a[x][y] = 0;//标记为0 
	for(int i= 0 ;i<4;i++){
			int xx = x + dx[i];
			int yy = y + dy[i];
			if(isvalid(xx,yy) && a[xx][yy] > 0){
				dfs(xx,yy);
			}
	}
	
} 

int main() {
    int _;
    scanf("%d", &_);
    while (_--) {
        
        scanf("%d %d", &n, &m);
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= m; j++) {
                scanf("%d", &a[i][j]);
            }
        }
        
        //边界为1的点满足搜索条件,加入搜索 
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= m; j++) {
                if (a[i][j] > 0 && (i == 1 || i == n || j == 1 || j == m)) {
					dfs(i,j);
                }
            }
        }
		
		//打印数组 
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= m; j++) {
            	if(j==m)
               	 printf("%d", a[i][j]);
               	else
               	  printf("%d ", a[i][j]);
            }
            printf("
"); 
        }
    }
    return 0;
}

代码二:bfs

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int INF = 0x3f3f3f3f;
const LL mod = 1e9 + 7;
const int N = 505;
int a[N][N];
int dx[4] = {0, 0, 1, -1};
int dy[4] = {1, -1, 0, 0};
typedef struct Node {
    int x, y;
};
int main() {
    int _;
    scanf("%d", &_);
    while (_--) {
        int n, m;
        scanf("%d %d", &n, &m);
        queue<Node> q;
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= m; j++) {
                scanf("%d", &a[i][j]);
                //边界为1的点 加入到队列 
                if (a[i][j] > 0 && (i == 1 || i == n || j == 1 || j == m)) {
                    q.push({i, j});
                    a[i][j] = 0;
                }
            }
        }
        //bfs搜索这些点的四周 若为1加入队列 
        while (!q.empty()) {
            int x = q.front().x, y = q.front().y;
            q.pop();
            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 <= m && a[tx][ty] > 0) {
                    q.push({tx, ty});
                    a[tx][ty] = 0;
                }
            }
        }
        //输出 
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= m; j++) {
            	if(j==m)
               	 printf("%d", a[i][j]);
               	else
               	  printf("%d ", a[i][j]);
            }
            printf("
"); 
        }
    }
    return 0;
}
原文地址:https://www.cnblogs.com/fisherss/p/10346127.html