TZOJ 7631: 无人机翱翔(深搜)


描述

江南校区的队员们准备参加无人机比赛了,为了庆祝出征,LZS想给大家弄一场表演,CJ给大家布置了一个N*M的矩阵场地,队员们可以操控无人机飞到坐标(i,j)(1<=i<=N,1<=j<=M)的位置。

对于每一个位置坐标(i,j),它有可能是空的,也有可能有一架无人机,且这个位置相邻的位置有左边、左上、上面、右上、右边、右下、下面、左下8个位置。所以在相邻位置上的无人机会被视为同一种队形。包含无人机数量相同的队形会被视为同一个阵容,而阵容的大小为阵容中所有无人机的数量。

ZZJ想考一考你,请你求出这个无人机表演里有多少种不同的队形,且最大的阵容大小是多少。

输入

输入一行N,M(2<=N,M<=150)表示矩阵的长宽

接下来N行每行M个字符,每个字符只会是"."或"*",其中"."表示该位置为空,"*"表示该位置有一架无人机

输出

输出仅一行两个整数,用空格隔开,分别表示队形的数量与最大阵容的大小。

样例输入

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

样例输出

3 4

提示

样例输入2:

10 10

**..**.**.

***....*..

*...**.**.

...*..*...

..........

**...**.*.

..*.*....*

..........

***..*.*..

.***..*...

样例输出2:

4 12

题意:队形大小就是无人机有多少个是相邻的,阵容大小就是有队形大小*队形数量;所以考虑到数据范围并不大,就可以把队形看作是1到150*150的桶,然后扫一遍地图,如果搜到i,j位置有无人机并且没有被标记过,就搜一遍,搜出来的队形大小就让该大小的桶值++,扫完地图后扫一遍桶,把桶的值*桶下标来计算最大阵容

代码

#include
using namespace std;
#define N 1510 
char a[N][N];
bool book[N][N];
int star[N*N];
int n,m,sum,Max=0;
int nex[8][2] = {{0,1},{1,1},{1,0},{1,-1},{0,-1},{-1,-1},{-1,0},{-1,1}};
void dfs(int x,int y)
{
    int tx,ty;
    sum++;
    book[x][y] = 1;
    for(int i=0;i<8;i++)
    {
        tx = x+nex[i][0];
        ty = y+nex[i][1];
        if(tx<1||tx>n||ty<1||ty>m)continue;
        if(a[tx][ty]=='*'&&book[tx][ty]!=1)
        {
            dfs(tx,ty);
        }
    }
}
int main()
{
    cin>>n>>m;
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=m;j++)
        {
            cin>>a[i][j];
        }
        getchar();
    }
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=m;j++)
        {
            if(a[i][j]=='*'&&book[i][j]!=1)
            {
                sum = 0;
                dfs(i,j);
                star[sum]++;
                if(sum*star[sum]>Max)Max = sum*star[sum];
            } 
        }
    }
    int ans = 0;
    for(int i=1;i<=n*m;i++)
    {
        if(star[i]>=1)ans++;
    }
    cout<" "<<Max;
     return 0;
}