对于这道题目来说的话,我们的思路是这样的,我们首先把数据读进来,然后把color数组清零。
我们的思路是这样的的,给每一个房间设置一个对应的color数组,然后color数组里面填满不同的数字,每一种数字都代表着一种联通的房间。
相互联通房间里面,对应的color数组填的就是相同的数字,然后对每个房间计数,然后比较之后得出最大的计数值就行了。
那我么怎么对这房间里面填不同的数字呢?
那就用深搜进行图的遍历就行了。
我们使用for循环对整个读入的rooms数组进行遍历,如果它对应的color格子不为零的话,我们就不进行DFS搜索,如果为零的话就说明它目前还是一个单独的单元格,因为我们在DFS的过程中是要修改对应的color值的。
对于DFS的话,就是DFS遍历的格式,如果是旧节点的话,我们就return ;
如果是不是的话我们,就进行染色,也就是相对应的写入color数组值,在这里面的话我们顺便进行一下,该联通空间的大小计数,每次进入for循环,if判断条件为真的话,我们就将roomArea清零,然后才进入深搜计数。
roomArea操作完之后,是要先将roomNum++的,这对应这不同的联通图。
DFS里面染色之后,就是深搜的方向了,题目中给的深搜方向是很方便的,我们对于给出的数字进行 1 2 4 8 的与运算,如果是零,就说明这地方没有砖,我们就可以直接深搜这个方向就可以了。
对于二进制来说 0001 是1 ,0010 是2, 0100 是4 ,1000 是8 。
#include <iostream>
#include <stack>
#include <cstring>
using namespace std;
int rooms[60][60],color[60][60];
int maxRoomArea=0,roomNum=0;
int roomArea;
void Dfs(int i,int k)
{
if (color[i][k]!=0) {
return ;
}
roomArea++;
color[i][k]=roomNum;
if ((rooms[i][k]&1)==0) Dfs(i,k-1);
if ((rooms[i][k]&2)==0) Dfs(i-1,k);
if ((rooms[i][k]&4)==0) Dfs(i,k+1);
if ((rooms[i][k]&8)==0) Dfs(i+1,k);
}
int main()
{
int R,C;
cin>>R>>C;
for (int i=1;i<=R;i++) {
for (int j=1;j<=C;j++) {
cin>>rooms[i][j];
}
}
memset(color,0,sizeof(color));
for (int i=1;i<=R;i++) {
for (int k=1;k<=C;k++) {
if (!color[i][k]) {
roomNum++;
roomArea=0;
Dfs(i,k);
maxRoomArea=max(roomArea,maxRoomArea);
}
}
}
cout<<roomNum<<endl
<<maxRoomArea<<endl;
return 0;
}