总时间限制: 1000ms 内存限制: 65536kB

描述

  1. 1 2 3 4 5 6 7
  2. #############################
  3. 1 # | # | # | | #
  4. #####---#####---#---#####---#
  5. 2 # # | # # # # #
  6. #---#####---#####---#####---#
  7. 3 # | | # # # # #
  8. #---#########---#####---#---#
  9. 4 # # | | | | # #
  10. #############################
  11. (图 1)
  12. # = Wall
  13. | = No wall
  14. - = No wall

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

输入

程序从标准输入设备读入数据。第一行是两个整数,分别是南北向、东西向的方块数。在接下来的输入行里,每个方块用一个数字(0 ≤ p ≤ 50)描述。用一个数字表示方块周围的墙,1表示西墙,2表示北墙,4表示东墙,8表示南墙。每个方块用代表其周围墙的数字之和表示。城堡的内墙被计算两次,方块(1,1)的南墙同时也是方块(2,1)的北墙。输入的数据保证城堡至少有两个房间。

输出

城堡的房间数、城堡中最大房间所包括的方块数。结果显示在标准输出设备上。

样例输入

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

样例输出

  1. 5
  2. 9

思路

抽象建模

  • 把方块看成节点, 相邻的两个方块之间如果没有墙, 则在方块之间相连一条边, 这样城堡问题就能转换为一个图.

  • 求房间个数, 实际上就是求图中有多少个极大连通子图.

  • 一个连通子图, 往里头加任何一个图里的其他点, 就会变得不连通, 那么这个连通子图就是极大连通子图.

  • 对每一个房间, 深度优先搜索, 从而给这个房间能够到达的所有位置染色. 最后统计一个用了几种颜色, 以及每种颜色的数量.
    比如:

    1. 1 1 2 2 3 3 3
    2. 1 1 1 2 3 4 3
    3. 1 1 1 5 3 5 3
    4. 1 5 5 5 5 5 3


从而一共有5个房间, 最大房间(1)占据了9个格子

代码

  1. #include <iostream>
  2. #include <algorithm>
  3. #include <cstring>
  4. using namespace std;
  5. int room[60][60];
  6. int color[60][60]; // 走过一个新方块就染色
  7. int maxRommArea = 0, roomNum = 0;
  8. int roomArea;
  9. void DFS(int i, int j) {
  10. if( color[i][j] )
  11. return;
  12. roomArea++;
  13. color[i][j] = roomNum;
  14. if( (room[i][j] & 1) == 0 ) DFS(i, j-1); // 走西边
  15. if( (room[i][j] & 2) == 0 ) DFS(i-1, j); // 走北边
  16. if( (room[i][j] & 4) == 0 ) DFS(i, j+1); // 走东边
  17. if( (room[i][j] & 8) == 0 ) DFS(i+1, j); // 走南边
  18. }
  19. int main() {
  20. int Row, Col;
  21. cin >> Row >> Col;
  22. for(int i = 1; i <= Row; i++) {
  23. for(int j = 1; j <= Col; j++) {
  24. cin >> room[i][j];
  25. }
  26. }
  27. memset(color, 0x0, sizeof(color));
  28. /* 遍历每个点 */
  29. for(int i = 1; i <= Row; i++) {
  30. for(int j = 1; j <= Col; j++) {
  31. if( !color[i][j] ) {
  32. roomNum++;
  33. roomArea = 0;
  34. DFS(i, j); // 在深度优先搜索后会设置当前房间的面积
  35. maxRommArea = max(roomArea, maxRommArea);
  36. }
  37. }
  38. }
  39. cout << roomNum << endl;
  40. cout << maxRommArea << endl;
  41. return 0;
  42. }