抠图|计蒜客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("\n");
}
}
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("\n");
}
}
return 0;
}