百练2815:城堡问题

来源:互联网 发布:淘宝发红包的钱在哪里 编辑:程序博客网 时间:2024/05/16 09:59

2815:城堡问题


总时间限制: 

1000ms

 

内存限制: 

65536kB

描述


图1是一个城堡的地形图。请你编写一个程序,计算城堡一共有多少房间,最大的房间有多大。城堡被分割成m´n(m≤50,n≤50)个方块,每个方块可以有0~4面墙。

输入

程序从标准输入设备读入数据。第一行是两个整数,分别是南北向、东西向的方块数。在接下来的输入行里,每个方块用一个数字(0≤p≤50)描述。用一个数字表示方块周围的墙,1表示西墙,2表示北墙,4表示东墙,8表示南墙。每个方块用代表其周围墙的数字之和表示。城堡的内墙被计算两次,方块(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

 

解题思路:

对每一个房间,深度优先搜索,从而给这个房间所能到达的所有房间进行染色(标记访问)。最后统计用了几种颜色,以及每种颜色的数量。

关于房间的四面的墙壁,题目中用的是周围墙的数字之和表示,考虑到1248的特殊性,即

1=(0000 0001)2            

2=(0000 0010)2

4=(0000 0100)2

8=(0000 1000)2

1248每一个整数和二进制的某一位一一对应,

如果给定整数 5=0000 01012,我们即刻知道其是1(0000 0001)40000 0001)的和,在这里我们通过和1248进行与(&)运算,便可得到给定整数的分解。

5&1=0000 0101 & 0000 0001 = 1

   5&2=0000 0101 & 0000 0010 = 0

   5&4=0000 0101 & 0000 0100 = 1

   5&8=0000 0101 & 0000 1000 = 0

表示541相加得到。

 

与的运算法则(二进制表示)

0&0 = 00&1 = 01&0 = 01&1 = 1.

 

程序代码:

#include "iostream"

#include "cstdio"

#include "cstring"

using namespace std;

 

int n,m;

int arr[55][55];

int color[55][55];

int Count=0;

int mj,maxMj=0;

 

void dfs(int x,int y){

// if(x < 0||x >=n||y < 0||y >= m) return;

if(color[x][y]!=0) return;

color[x][y]=1;

mj++;

// cout << x<<","<<y<<endl;

if((arr[x][y]&1)==0) dfs(x,y-1);

if((arr[x][y]&2)==0) dfs(x-1,y);

if((arr[x][y]&4)==0) dfs(x,y+1);

if((arr[x][y]&8)==0) dfs(x+1,y);

}

 

 

 

int main(){

memset(color,0,sizeof(color));

scanf("%d%d",&n,&m);

int i,j;

for(i = 0;i < n; i++){

for(j = 0;j < m; j++){

scanf("%d",&arr[i][j]);

}

}

for(i = 0;i < n; i++){

for(j = 0;j < m; j++){

if(color[i][j]==0) {

mj=0;

dfs(i,j);

Count++;

if(mj > maxMj) maxMj = mj;

}

}

}

cout << Count <<endl;

cout << maxMj << endl;

//dfs(0,0);

return 0;

}

 

提交结果:


0 0
原创粉丝点击