P5198 [USACO19JAN]Icy Perimeter S

https://www.luogu.com.cn/problem/P5198
搜索
黄色题
思路:

这道题个人认为用dfs比较好理解

但是dfs有可能或爆栈

所以一下代码仅供参考

冰淇淋的面积用dfs很好求

只要算出每个联通块中'#'的个数即可

难点(?)在于求联通快的周长

其实也很好想

观察一下样例 发现周长就是每个'#'周围'.'或超过边界的方块个数

解决这一问题后这道题几乎就是一道dfs裸题了


 

#pragma GCC optimize("no-stack-protector")//对堆栈的一点优化(或许可以防止爆栈)
#include<iostream>
#define HAND
const int MAXN=1e3+7;
const int dx[]= {0,1,0,-1},dy[]= {1,0,-1,0};
int n,S,C,mxs,mic;//S是面积 C是周长
char ice[MAXN][MAXN];
bool vis[MAXN][MAXN];
void dfs(int x,int y) {
    if(vis[x][y])
        return ;
    vis[x][y]=true;
    S++;
    for(int d=0; d<4; d++) {
        int xx=x+dx[d],yy=y+dy[d];
        if(xx<1||xx>n||yy<1||yy>n||ice[xx][yy]=='.')//注意周长条件处理
            C++;
        if(ice[xx][yy]=='#')
            dfs(xx,yy);
    }
    return ;
}
void solve(void) {
    std::cin>>n;
    for(int i=1; i<=n; i++)
        std::cin>>ice[i]+1;
    for(int i=1; i<=n; i++) {
        for(int j=1; j<=n; j++) {
            if(ice[i][j]=='#'&&!vis[i][j]) {
                S=C=0;
                dfs(i,j);
                if(S>mxs) {
                    mxs=S;
                    mic=C;
                } else if(S==mxs)
                    mic=std::min(mic,C);
            }
        }
    }
    std::cout<<mxs<<' '<<mic;
}
int main(void) {
#ifdef HANDIN
    freopen("perimeter.in","r",stdin);
    freopen("perimeter.out","w",stdout);
#endif
    solve();
    return 0;
}
 

 

posted @ 2022-08-12 09:30  -イレイナ  阅读(63)  评论(0)    收藏  举报