【Luogu P6566】【NOI Online 入门组】观星

观 星 观星


L u o g u P 6566 Luogu P6566 LuoguP6566


题目描述

Jimmy 和 Symbol 约好一起看星星,浩瀚的星空可视为一个长为 N、宽为 M 的矩阵,矩阵中共有 N×M 个位置,一个位置可以用坐标 *(i,j)( 1≤i≤N,1≤j≤M )*来表示。每个位置上可能是空的,也可能有一个星星。

对于一个位置 (i,j),与其相邻的位置有左边、左上、上面、右上、右边、右下、下面、左下 8 个位置。相邻位置上的星星被视为同一个星座,这种关系有传递性,例如若 (1,1),(1,2),(1,3)(1,1),(1,2),(1,3) 三个 位置上都有星星,那么这三个星星视为同一个星座。包含的星星数量相同的星座被视为一个星系(一个星系中的星座不一定相邻),星系的大小为星系中包含的所有星星数量。

由于 Symbol 太喜欢星系了,他就想考一考 Jimmy,让 Jimmy 求出星空中有多少个星系,他还想知道,最大的星系有多大。


输入格式

第一行两个整数 N,M 表示矩阵的长宽。

接下来 N 行每行 M 个字符,每个字符只可能是.或*。这 N 行中第 i 行的第 j 个字符是*表示位置 (i,j) 上有一个星星,否则表示它是空的。

输出格式

仅一行两个整数,用空格分隔开,分别表示星系的数量与最大星系的大小。


输入输出样例

输入#1

5 7
*......
..**..*
.*...*.
...*...
....*..

输出#1

3 4

输入#2

10 10
**..**.**.
***....*..
*...**.**.
...*..*...
..........
**...**.*.
..*.*....*
..........
***..*.*..
.***..*...

输出#2

4 12

说明/提示

  • 对于 20% 的数据,N,M≤20,最大星系大小不超过 200
  • 对于 50% 的数据,N,M≤400
  • 对于 70% 的数据,N,M≤1100
  • 对于 100% 的数据,2≤N,M≤1500,最大星系大小不超过 100000

解题思路

  • 这道题是一个DFS,只要找到一个星星之后就不断搜索周围的加上统计即可。
  • (主要是理解好星座和星系的求法即可)

程序如下

#include
#include
#include
#include
using namespace std;
const int dx[8] = {
     0,0,1,1,1,-1,-1,-1};
const int dy[8] = {
     1,-1,1,0,-1,1,0,-1};
int n,m,sum,tj[10000001],Max,ans;
char a;
bool t[10001][10001];
void d(int x,int y)//DFS来判断星座和星系
{
     
	sum++;
	t[x][y] = false;
	for(int i = 0;i < 8; ++i)
	{
     
		if(x + dx[i] > 0 && x + dx[i] <= n && y + dy[i] > 0 && y + dy[i] <= m && t[x + dx[i]][y + dy[i]])
		{
     
			d(x + dx[i], y + dy[i]);
		}
	}
}
int main()
{
     
	scanf("%d%d",&n,&m);
	for(int i = 1;i <= n ; ++i)
	{
     
		for(int j = 1;j <= m; ++j)
		{
     
			cin>>a;
			if(a == '*') t[i][j] = true;
		}
	}
	for(int i = 1;i <= n; ++i)
	{
     
		for(int j = 1;j <= m; ++j)
		{
     	
			if(t[i][j])
			{
     
				d(i, j); 
				tj[sum]++;
				if(sum * tj[sum] > Max) Max = sum * tj[sum];//统计星系
				sum = 0;
			}
		}
	}
	for(int i = 0;i <= n * m; ++i)
	{
     
		if(tj[i]) //所在星系最多的星星
		{
     
			ans++;
		}
	}
	printf("%d %d",ans,Max);
	return 0;
}

你可能感兴趣的:(DFS)