卫星照片

Description

农夫 John 正在研究他的农场的卫星照片.照片为一个R (1 <=R <= 75) 行 C (1 <= C <= 75) 列的字符矩阵表示.如下图:
..#####…….##..
..#####……##…
………………
#…….###…..#.
#…..#####…….
图上的一块相连通的 “#” 表示一群奶牛或一个房间, 两个子”#” 连通的意思是说左右或上下相连.而下面的两块则是分开的:
….
.#..
..#.
….
John现在根据卫星照片上的的这些”#”块的形状来判断哪些是牛群,哪些是房间.如果一个”#”块形状的边是水平或垂直的矩形,则是房间.其它的则认为都是牛群.在第一个图中,有三个房间 ( 2x1, 2x5, and 1x1)和2群牛.
请根据输入文件中的数据,统计出房间数和牛群数.
数据中牛群不会包围另一个牛群或房间.

Input

  • 第一行,两个整数: R 和 C.
    • 和 2..R+1行: 第 i+1 行表示照片的第 i 行情况,由 C 字符组成.

Output

  • 第一行: 房间数.
    • 第二行: 牛群数.

Sample Input
5 8

..
.

……#.
.###…#
.###..##

Sample Output
2
2

题解:

暴力每个点,找到又“#”组成的块。然后找一个刚好能保住这个块的矩形,得出这矩形的左上角和右下角,枚举矩形里有多少个“#”,比较是否等于矩形的点数,若相等则这个块是矩形,亦反之。

代码:

var
  n,m,ans1,ans2:longint;
  o,p,l,r:longint;
  a:array [0..80,0..80] of boolean;
  c:array [0..80,0..80] of char;
procedure init;
var
  i,j:longint;
begin
  readln(n,m);
  for i:=1 to n do
    begin
      for j:=1 to m do
        read(c[i,j]);
      readln;
    end;
end;

procedure search(x,y:longint);
begin
  if (x<1) or (x>n) or (y<1) or (y>m) or (c[x,y]<>'#') or (not a[x,y]) then exit;
  a[x,y]:=false;
  if x<o then o:=x;
  if y<p then p:=y;
  if x>l then l:=x;
  if y>r then r:=y;
  search(x+1,y);
  search(x-1,y);
  search(x,y-1);
  search(x,y+1);
end;

procedure main;
var
  i,j,num,x,y:longint;
begin
  ans1:=0; ans2:=0;
  fillchar(a,sizeof(a),true);
  for i:=1 to n do
    for j:=1 to m do
      if (a[i,j]) and (c[i,j]='#') then
        begin
          num:=0;
          o:=i; p:=j; l:=i; r:=j;
          search(i,j);
          for x:=o to l do
            for y:=p to r do
              if c[x,y]='#' then
                inc(num);
          if num=(l-o+1)*(y-p+1) then inc(ans1)
                                 else inc(ans2);
        end;
  writeln(ans1,' ',ans2);
end;

begin
  init;
  main;
end.

原文地址:https://www.cnblogs.com/zyx-crying/p/9319500.html