原题链接:https://www.acwing.com/problem/content/1100/
由于对于每个点,使用了二进制表示,表示其上下左右的墙的情况。墙和非墙是不占用输入的,而且不用在单独建图!!只需要在BFS的时候判断能不能走就行。
//墙和非墙是不占用输入的,而且不用在单独建图!!
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
#define x first
#define y second
typedef pair<int, int> PII;
const int N=55, M=N*N;
int n, m;
int g[N][N];
PII q[M];
bool st[N][N];
// 竖着的是x轴,横着的是y轴。
//返回此联通块的面积
int bfs(int sx, int sy)
{
//这个顺序很重要,由西顺时针到南,x和y轴搞明白!
int dx[4]={0, -1, 0, 1}, dy[4] = {-1, 0, 1, 0};
int hh=0, tt=0;
int area=0;
q[0]={sx, sy};
st[sx][sy]=true;
while(hh<=tt)
{
PII t=q[hh++];
area++; // 在每次出队的时候统计,入队的时候也行。
for(int i=0; i<4; i++)
{
int a=t.x+dx[i], b=t.y+dy[i];
if(a<0 || a>=n || b<0 || b>=m) continue;
if(st[a][b]) continue;
// i从0到3,西,北,东,南。
if(g[t.x][t.y] >> i & 1) continue;
q[++tt]={a, b};
st[a][b]=true;
}
}
return area;
}
int main()
{
cin>>n>>m;
for(int i=0; i<n; i++)
for(int j=0; j<m; j++)
cin>>g[i][j];
int cnt=0, area=0;
for(int i=0; i<n; i++)
for(int j=0; j<m; j++)
{
if(!st[i][j])
{
// 这里属性还需要维护一个最大值。
area=max(area, bfs(i, j));
cnt++;
}
}
cout<<cnt<<endl;
cout<<area<<endl;
return 0;
}