洛谷P1162 传送门
先上原题:
题目就是要找到一个封闭的图形,即被1
完全包围的0
。封闭图形保证一定有且只有一个。
显然,图形的最外面一圈的0
肯定不是封闭图形的一部分,所以刚开始我想搜索除了最外圈
以外的0
,只要搜索遇到了边界就不满足题意。但是后来写的过程中还是发现存在一些问题。
然后就开始想别的思路,其实可以发现,既然封闭图形只有一个,不封闭的图形一定会到达边界,那么我们可以反着来,把所有不封闭的图形都找出来,那么封闭图形也就知道了,所以思路就是把最外圈的0
全部用bfs搜索,标记所有不封闭的0
代码如下:
#include <stdio.h>
#include <cstring>
#include <iostream>
#include <string>
#include <cmath>
#include <algorithm>
#include <cstdlib>
#include <queue>
#include <deque>
#include <cstring>
#include <iterator>
#include <set>
#include <map>
using namespace std;
#define ll long long
int mp[35][35];
int mov[4][2] = {1, 0, 0, 1, -1, 0, 0, -1};
int vis[35][35];
int vis2[35][35];//标记与最外圈的0相连的所有0
int n;
int dfs(int x, int y)
{
vis2[x][y] = 1;
for (int i = 0; i < 4; i++)
{
int xx = x + mov[i][0];
int yy = y + mov[i][1];
if (xx < 1 || yy < 1 || xx > n || yy > n || vis[xx][yy] || mp[xx][yy])
continue;
vis[xx][yy] = 1;
dfs(xx, yy);
}
}
int main()
{
cin >> n;
for (int i = 1; i <= n; i++)
for (int j = 1; j <= n; j++)
cin >> mp[i][j];
for (int i = 1; i <= n; i++)
if (mp[i][1] == 0)
dfs(i, 1);
for (int i = 1; i <= n; i++)
if (mp[i][n] == 0)
dfs(i, n);
for (int j = 1; j <= n; j++)
if (mp[1][j] == 0)
dfs(1, j);
for (int j = 1; j <= n; j++)
if (mp[n][j] == 0)
dfs(n, j);
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= n; j++)
if (mp[i][j] == 0 && vis2[i][j] == 0)
printf("2 ");
else
printf("%d ", mp[i][j]);
cout << endl;
}
return 0;
}