帮 大一学弟 AC一道题
问题描述
网格地图是由n行n列的网格组成,每个网格初始时用0填充。地质测绘人员在网格地图上用数字1将唯一的湖泊边界围成一圈,围圈时只能沿著上下左右4个方向。湖泊是被数字1围成的区域(不包含1),请你编写程序,将湖泊的范围用数字2进行埴充。输入形式
第一行输入一个整数n(0<n<=30);
下面n行,每个由空格隔开的0或者1组成。输出形式
输出n行n列,将湖泊的区域用2标识。
样例1输入
6
0 0 0 0 0 0
0 1 1 1 1 1
0 1 0 0 0 1
0 1 0 0 1 1
0 1 1 0 1 0
0 0 1 1 1 0
样例1输出
0 0 0 0 0 0
0 1 1 1 1 1
0 1 2 2 2 1
0 1 2 2 1 1
0 1 1 2 1 0
0 0 1 1 1 0
样例2输入
4
0 1 1 1
1 1 0 1
1 0 0 1
1 1 1 1
样例2输出
0 1 1 1
1 1 2 1
1 2 2 1
1 1 1 1
样例3输入
4
1 1 1 1
1 0 0 1
1 0 0 1
1 1 1 1
样例3输出
1 1 1 1
1 2 2 1
1 2 2 1
1 1 1 1
同类型的题目《岛屿问题》在leetcode上出现过,这类题目主要通过搜索算法(深搜dfs或广搜bfs)去解决,较有难度的要剪枝才能通过,这里我们主要用队列这一数据结构+pair技术去实现。
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <queue>
using namespace std;
typedef pair<int, int> PII;
int dir[4][2] = {-1, 0, 1, 0, 0, -1, 0, 1};
int a[40][40], vis[40][40];
int main()
{
int n; scanf("%d", &n);
for (int i = 1; i <= n; i++)
for (int j = 1; j <= n; j++)
scanf("%d", &a[i][j]);
queue<PII> qu;
for (int i = 0; i <= n + 1; i++)
for (int j = 0; j <= n + 1; j++)
if (i == 0 || i == n + 1 || j == 0 || j == n + 1)
{
qu.push(make_pair(i, j)), vis[i][j] = 1;
}
while (!qu.empty())
{
PII p = qu.front(); qu.pop();
int x = p.first, y = p.second;
for (int i = 0; i < 4; i++)
{
int nx = x + dir[i][0], ny = y + dir[i][1];
if (nx < 0 || nx > n + 1 || ny < 0 || ny > n + 1 || a[nx][ny] || vis[nx][ny]) continue;
qu.push(make_pair(nx, ny)), vis[nx][ny] = 1;
}
}
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= n; j++)
{
if (a[i][j] == 0 && vis[i][j] == 0) a[i][j] = 2;
if (j > 1) printf(" ");
printf("%d", a[i][j]);
}
printf("\n");
}
return 0;
}