———————————本文旨在讨论和探究计算机知识,欢迎指正交流—————————
观察这道题目,笔者也是很懵,对于上下左右求和的形式来反映墙的位置感到束手无策。第一次,笔者想用静态数组存起来遍历,但是发现要弄几十种传参判断,绝对会超时,于是作罢。
第二天笔者想到1,2,4,8正好满足二进制数:
1=0001;
2=0010;
4=0100;
8=1000;
于是根据二进制的性质,我们只用把每次的和与东南西北对应的值进行&即可。
int dfs(int i,int j)//于是就有了如下的深搜代码
{
if(vis[i][j])return 0;//如果走过这一点则不重复走,跳过;
vis[i][j]=true;//这一点未走过,标记一下,下次不走
int place=1;//标记这个空房间为1,下次,递归相加求总房间大小
if(!(f[i][j]&1))place+=dfs(i,j-1);//递归过程,走可以走的地方
if(!(f[i][j]&2))place+=dfs(i-1,j);
if(!(f[i][j]&4))place+=dfs(i,j+1);
if(!(f[i][j]&8))place+=dfs(i+1,j);
return place;//返回空房间大小
}
解决了这一核心问题,我们来编写主函数:
int main()
{
cin>>m>>n;//行列数
for(int i=1;i<=m;i++)
{
for(int j=1;j<=n;j++)
{
cin>>f[i][j];//输入每个房间的特征值
}
}
for(int i=1;i<=m;i++)
{
for(int j=1;j<=n;j++)
{
if(!vis[i][j])
{
roomcnt++;//如果是空的,则房间数+1;
int roomplace=dfs(i,j);//求房间大小并进行标记,下次不走了
maxnsum=max(maxnsum,roomplace);//最大房间大小
}
}
}
cout<<roomcnt<<endl;
cout<<maxnsum<<endl;
return 0;
}
好了,下面是完整代码:
#include<bits/stdc++.h>
using namespace std;
const int N=100;
int f[N][N];
bool vis[N][N];
int n,m;
int roomcnt=0,maxnsum=0;
int dfs(int i,int j)
{
if(vis[i][j])return 0;
vis[i][j]=true;
int place=1;
if(!(f[i][j]&1))place+=dfs(i,j-1);
if(!(f[i][j]&2))place+=dfs(i-1,j);
if(!(f[i][j]&4))place+=dfs(i,j+1);
if(!(f[i][j]&8))place+=dfs(i+1,j);
return place;
}
int main()
{
cin>>m>>n;
for(int i=1;i<=m;i++)
{
for(int j=1;j<=n;j++)
{
cin>>f[i][j];
}
}
for(int i=1;i<=m;i++)
{
for(int j=1;j<=n;j++)
{
if(!vis[i][j])
{
roomcnt++;
int roomplace=dfs(i,j);
maxnsum=max(maxnsum,roomplace);
}
}
}
cout<<roomcnt<<endl;
cout<<maxnsum<<endl;
return 0;
}
希望能对你有所帮助!