算法实践:城堡问题(DFS)

城堡问题

描述

     1   2   3   4   5   6   7  
   #############################
 1 #   |   #   |   #   |   |   #
   #####---#####---#---#####---#
 2 #   #   |   #   #   #   #   #
   #---#####---#####---#####---#
 3 #   |   |   #   #   #   #   #
   #---#########---#####---#---#
 4 #   #   |   |   |   |   #   #
   #############################
           (图 1)

   #  = Wall   
   |  = No wall
   -  = No wall

图1是海拉鲁城堡的地形图。请你编写一个程序,计算该城堡一共有多少房间,最大的房间有多大。

城堡被分割成m×n(m≤50,n≤50)个方块,每个方块可以有0~4面墙。

输入

前两行是两个整数,分别是南北向、东西向的方块数(行和列)。

在接下来的输入行里,每个方块用一个数字p表示(0≤p≤50)。其二进制位为1代表有墙,为0代表无墙。

四面墙由整数P的后四位表示。最低位代表西墙(0001),第二位代表北墙(0010),第三位4表示东墙(0100),第四位表示南墙(1000)。

四个数相加的和就是每个方块的四面墙的状态。

输入数据中每个方块的内墙是重叠的,方块(1,1)的南墙同时也是方块(2,1)的北墙。

输入的数据保证城堡至少有两个房间。

输出

海拉鲁城堡的房间数、海拉鲁城堡中最大房间所包括的方块数。

结果显示在标准输出设备上。

样例

4 
7 
11 6 11 6 3 10 6 
7 9 6 13 5 15 5 
1 10 12 7 13 7 5 
13 11 10 8 10 12 13 
5
9

难度

中,DFS

解法

深度优先搜索求最大连通分支数

使用按位与运算发判断向下搜索条件。参加运算的两个数据,按二进制位进行“与”运算。

运算规则:0&0=0; 0&1=0; 1&0=0; 1&1=1;

​ 即:两位同时为“1”,结果才为“1”,否则为0

例如:3&5 即 0000 0011 & 0000 0101 = 0000 0001 因此,3&5的值得1。

最低位代表西墙(0001),第二位代表北墙(0010),第三位4表示东墙(0100),第四位表示南墙(1000)。

代码

#include "bits/stdc++.h"
using namespace std;
int maze[60][60],M,N;
int book[60][60];
int roomnum=0,maxroom=0,room;//记录房间数、最大房间、目前房间大小;
void dfs(int x,int y){
    if(book[x][y]) return;
    room++;
    book[x][y]=1;
    if((maze[x][y]&1)==0) dfs(x,y-1);
    if((maze[x][y]&2)==0) dfs(x-1,y);
    if((maze[x][y]&4)==0) dfs(x,y+1);
    if((maze[x][y]&8)==0) dfs(x+1,y);
}
int main()
{
    cin>>M>>N;
    memset(book,0,sizeof(book));
    for(int i=0;i<M;i++) for(int j=0;j<N;j++) cin>>maze[i][j];
    for(int i=0;i<M;i++) for(int j=0;j<N;j++){
        if(!book[i][j])
        {
            room=0;
            roomnum++;
            dfs(i,j);
            maxroom=maxroom>room?maxroom:room;
        }
    }
    cout<<roomnum<<endl<<maxroom<<endl;
    return 0;
}
发布了129 篇原创文章 · 获赞 148 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/matafeiyanll/article/details/105248352