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<bits/stdc++.h> 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<<ans<<" "<<Max; return 0; }