Time Limit: 1 second
Memory Limit: 64 MB
【问题描述】
农夫 John 正在研究他的农场的卫星照片.照片为一个R (1<= R <= 75) 行C (1<=C<=75) 列的字符矩阵表示。如下图:
..................
..#####.......##..
..#####......##...
..................
#.......###.....#.
#.....#####.......
图上的一块相连通的 “#” 表示一群奶牛或一个房间, 两个子”#” 连通的意思是说左右或上下相连。而下面的两块则是分开的:
....
.#..
..#.
....
John现在根据卫星照片上的的这些”#”块的形状来判断哪些是牛群,哪些是房间。如果矩形内只有‘#’,则是房间。其它的则认
为都是牛群。在第一个图中,有三个房间 ( 2x1, 2x5, and 1x1)和2群牛。
根据输入文件的数据,统计出房间数和牛群数,数据中牛群不会包围另一个牛群或房间。
【输入格式】
第一行,两个整数: R 和 C. 和 2..R+1行: 第 i+1 行表示照片的第 i 行情况,由 C 字符组成。
【输出格式】
第一行: 房间数。 第二行: 牛群数。
【数据规模】
Sample Input1
5 8
#####..#
#####.##
......#.
.###...#
.###..##
Sample Output1
2
2
【题目链接】:http://noi.qz5z.com/viewtask.asp?id=u246
【题解】
题意:
让你求图中的连通块的形状是不是矩形、是矩形就为房子否则为牛群;
递增相应答案;
做法:
bfs、floodfill;
在做bfs的时候;记录你到过的横坐标最小的Minx和最大的maxx;以及最小的纵坐标miny以及最大的纵坐标maxy;
然后记录这个连通块内的格子数目;然后看一下minxminy以及maxxmaxy对应的矩形应该有的格子数目;如果想等,那么连通块为矩形;否则不是矩形;
【完整代码】
#include <iostream>
#include <queue>
#include <cstring>
#include <cstdio>
using namespace std;
const int MAXN = 110;
const int dx[5] = {0,0,0,1,-1};
const int dy[5] = {0,1,-1,0,0};
int n,m,fz = 0,nq = 0;
int a[MAXN][MAXN];
queue <pair<int,int> > dl;
int main()
{
//freopen("F:\rush.txt","r",stdin);
memset(a,0,sizeof(a));
cin >> n >> m;
for (int i = 1;i <= n;i++)
{
char key;
for (int j = 1;j <=m;j++)
{
cin >> key;
if (key == '#')
a[i][j] = 1;
else
a[i][j] = 0;
}
}
for (int i = 1;i <= n;i++)
for (int j = 1;j <= m;j++)
if (a[i][j]==1)
{
int minx=i,maxx=i,miny=j,maxy=j;
a[i][j] = 0;
int now = 1;
dl.push(make_pair(i,j));
while (!dl.empty())
{
int x = dl.front().first,y = dl.front().second;
dl.pop();
for (int p = 1;p <= 4;p++)
{
int tx = x+dx[p],ty = y+dy[p];
if (a[tx][ty])
{
now++;
minx = min(minx,tx);maxx = max(maxx,tx);
miny = min(miny,ty);maxy = max(maxy,ty);
a[tx][ty] = 0;
dl.push(make_pair(tx,ty));
}
}
}
int chang = maxy-miny+1;
int kuan = maxx-minx+1;
int total = chang*kuan;
if (total == now)
fz++;
else
nq++;
}
cout << fz<<endl;
cout << nq<<endl;
return 0;
}