读题
当初看到这道题时,我的内心是奔溃的:
什么魔鬼输入?!
什么恶心要求?!
我 *(数据删除)
算了,还是好好做题吧。
输入处理
通过观察,我们可以知道每一个数都可以这样分解
假设某行有一个数 11 11 11,我们可以:把它拆成二进制:
11= 1 0 1 1
1/表示南面有墙
0/表示东面没有墙
1/表示北面有墙
1/表示西面有墙
所以我们可以设一个布尔类型三维数组 a [ i , j , 4 ] a[i,j,4] a[i,j,4]
表示第 i i i行第 j j j列西,北,东,南分别有木有墙。
那么问题来了:如何对每一位进行判断?
c++有一套特别神奇的东西,叫位运算。
用它们就可以进行对每一个二进制位的运算。
在这里,我假设你们都明白它们的作用,我们就可以将运算简化为这样:
for(int i=1;i<=m;i++)
for(register int j=1;j<=n;j++)
{
cin>>x;
for(int v=1;v<=4;v++) a[i][j][v]=1<<(v-1)&x;
}
第一部分(城堡的房间数目,最大的房间的大小)
这两个简单,可以直接一波BFS搞定
对BFS过的点进行标记,如果出现有未搜过的点就进行一次广搜并将计数器加一
上这一片段代码
for(int i=1;i<=m;i++)
for(int j=1;j<=n;j++)
if(!a[i][j][0])
{
y=1;
++d;
q.push((tt){
i,j});
while(!q.empty())
{
ww=q.front();
q.pop();
for(register int k=1;k<=4;k++)
if(!a[ww.x][ww.y][k]&&!b[ww.x+dx[k]][ww.y+dy[k]]