洛谷 P1162 填涂颜色

题目链接:填涂颜色



思路

       因为需要找出被所有1围住的0,但是发现直接查找会比较麻烦,会需要搜索判断四个方向都被1包围,然后还要再次搜素给这些0赋值。但是如果反向思维把不被1包围的0全部找出来剩下的就是被1包围的0了,可以使用搜索从在正方形边界上的0开始搜索,将所有能搜到的0全部标记,剩下的就是被1包围的0。
       此时我们把地图的边界扩大2个格子从(1 - n) -> (0 - n + 1),此时就不需要一个个去判断在边界上的元素是否是0了,因为可以直接从(0, 0)开始搜索,整个方阵周围多了一圈0,所以在方阵边界上的元素是0时,可以直接被搜索到。至于为什么不用(0 - n),因为可能会出现特殊情况导致方阵右下角未1包围的0没有被搜索到,如下图右下角的四个0就不会被搜索到,会被判定为被1包围的0。
image


代码

#include <bits/stdc++.h>
using namespace std;
const int N = 30 + 10;
#define ll long long

int mp[N][N], dir[5][2] = {
    { 1, 0 }, { 0, 1 }, { -1, 0 }, { 0, -1 } 
}, n;
bool vis[N][N];

bool check(int x, int y) {
  return x >= 0 && x <= n + 1 && y >= 0 && y <= n + 1;
}

bool BFS(int x, int y) {
  queue<pair<int, int>> q;
  q.push({x, y});

  while (!q.empty()) {
    pair<int, int> point = q.front();
    q.pop();
    for (int i = 0; i < 4; i++) {
      pair<int, int> dpoint = point;
      dpoint.first = point.first + dir[i][0];
      dpoint.second = point.second + dir[i][1];
      if (check(dpoint.first, dpoint.second)) {
        if (mp[dpoint.first][dpoint.second] == 0) {
          mp[dpoint.first][dpoint.second] = 3;
          q.push(dpoint);
        }
      }
    }
  }
  return true;
}
int main() {
  cin >> n;

  for (int i = 1; i <= n; i++) {
    for (int j = 1; j <= n; j++) {
      cin >> mp[i][j];
    }
  }

  BFS(0, 0);

  for (int i = 1; i <= n; i++) {
    for (int j = 1; j <= n; j++) {
      if (mp[i][j] == 3) {
        cout << 0 << " ";
      } else if (mp[i][j] == 0) {
        cout << 2 << " ";
      } else {
        cout << 1 << " ";
      }
    }
    cout << endl;
  }

  return 0;
}
posted @ 2024-06-16 14:08  薛定谔的AC  阅读(21)  评论(0)    收藏  举报