题目链接
刚看到这道题还是有点蒙圈的,想不到是搜索,知道搜索又不知道怎么搜.看了半天题解才反应过来.
这道题用的染色法,就是通过搜素进行标记,对标记进行处理进而求出答案.
这道题要求把所有围在1里的0标记为2后输出.直接找到这些0或者直接找围成圈的1是比较困难的(事实上我也是这么想才会完全没思路的).但可以从这个图上找到两个性质:
- 边上的0一定不会被围,因为它的四周一定有一面无法被围住.
- 被围住的0与外界的0一定不会有联通.
那么,从边上的0出发,试图寻找所有联通的0并标记,最后未被标记且不是1的格子就是需要被上色的0.
注意搜索的范围要比图案大一圈,因为需要考虑墙在边上的情况.
#include <bits/stdc++.h>
using namespace std;
const int N = 35;
int m[N][N];
bool flag[N][N];
int n;
queue<pair<int,int> > p;
int main()
{
cin >> n;
for(int i = 1 ; i <= n ; i++)
for(int j = 1 ; j <= n ; j++)
cin >> m[i][j];
p.push(make_pair(0,0));
flag[0][0] = true;
while(!p.empty())
{
int x = p.front().first;
int y = p.front().second;
if(!m[x][y])
flag[x][y] = true;
if(x && !m[x - 1][y] && !flag[x - 1][y])
p.push(make_pair(x - 1,y));
if(x <= n && !m[x + 1][y] && !flag[x + 1][y])
p.push(make_pair(x + 1,y));
if(y && !m[x][y - 1] && !flag[x][y - 1])
p.push(make_pair(x,y - 1));
if(y <= n && !m[x][y + 1] && !flag[x][y + 1])
p.push(make_pair(x,y + 1));
p.pop();
}
for(int i = 1 ; i <= n ; i++)
{
for(int j = 1 ; j <= n ; j++)
{
if(!flag[i][j] && !m[i][j])
cout << 2;
else
cout << m[i][j];
cout << ' ';
}
cout << endl;
}
return 0;
}