题解 P6566 【[NOI Online #3 入门组]观星(民间数据)】

· · 题解

其实这不是一道特别难的题……

这道题可以直接用DFS过。关键是要先读懂题目,分清“星系”和“星座”的意思。

难点是如何把星星数相同的星座划入同一星系。可以用一个数组把星星数相同的星座存入一个变量中。在此代码中,galaxy[ i ]用于存储有i颗星星的星座有多少个,易知i×galaxy[ i ]就是该星系的星星个数。(i就表示星系中每个星座星星的数量)

代码如下:

#include<bits/stdc++.h>
#define N 1502
using namespace std;
int n,m,dx[8]={0,0,1,1,1,-1,-1,-1},dy[8]={1,-1,1,0,-1,1,0,-1};//dfs八个方向的模板
int galaxy[N*N],sum,Max;
bool star[N][N];//用于存储每个坐标是否有星星
void Search(int x,int y){//dfs
    sum++;//储存搜索到的这个星座的星星数量
    star[x][y]=false;//设为已访问过
    for(int i=0;i<8;i++){//八个方向
        int xx=x+dx[i],yy=y+dy[i];
        if(xx>=1&&xx<=n&&yy>=1&&yy<=m&&star[xx][yy])
            Search(xx,yy);
    }
}
int main(){
//  freopen("star.in","r",stdin);
//  freopen("star.out","w",stdout);
    char c;
    cin>>n>>m;
    for(int i=1;i<=n;i++){//将输入结果存入star数组
        for(int j=1;j<=m;j++){
            cin>>c;
            if(c=='*')star[i][j]=true;
        }
    }
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            if(star[i][j]){
                Search(i,j);
                galaxy[sum]++;
                if(sum*galaxy[sum]>Max)Max=sum*galaxy[sum];//用于计算最大的星系,sum*galaxy[sum]的意义详见上面
                sum=0;
            }
        }
    }
    int ans=0;
    for(int i=0;i<=n*m;i++){
        if(galaxy[i])ans++;//用于计算星系的数量
    }
    cout<<ans<<' '<<Max;
    return 0;
}

Thanks for your reading!And please don't be a cheater!