完整题目及翻译 + 题解
2024-03-19 20:56:50
发布于:陕西
完整题目及翻译:
[USACO19JAN] Icy Perimeter S
题目背景
USACO一月月赛银组第二题
题目描述
Farmer John要开始他的冰激凌生意了!他制造了一台可以生产冰激凌球的机器,然而不幸的是形状不太规则,所以他现在希望优化一下这台机器,使其产出的冰激凌球的形状更加合理。
机器生产出的冰激凌的形状可以用一个N×N(1≤N≤1000)的矩形图案表示,例如:
##....
....#.
.#..#.
.#####
...###
....##
每个'.'字符表示空的区域,每个'#'字符表示一块1×1的正方形格子大小的冰激凌。
不幸的是,机器当前工作得并不是很正常,可能会生产出多个互不相连的冰激凌球(上图中有两个)。一个冰激凌球是连通的,如果其中每个冰激凌的正方形格子都可以从这个冰激凌球中其他所有的冰激凌格子出发重复地前往东、南、西、北四个方向上相邻的冰激凌格子所到达。
Farmer John想要求出他的面积最大的冰激凌球的面积和周长。冰激凌球的面积就是这个冰激凌球中'#'的数量。如果有多个冰激凌球并列面积最大,他想要知道其中周长最小的冰激凌球的周长。在上图中,小的冰激凌球的面积为2,周长为6,大的冰激凌球的面积为13,周长为22。
注意一个冰激凌球可能在中间有“洞”(由冰激凌包围着的空的区域)。如果这样,洞的边界同样计入冰激凌球的周长。冰激凌球也可能出现在被其他冰激凌球包围的区域内,在这种情况下它们计为不同的冰激凌球。例如,以下这种情况包括一个面积为1的冰激凌球,被包围在一个面积为16的冰激凌球内:
#####
#...#
#.#.#
#...#
#####
同时求得冰激凌球的面积和周长十分重要,因为Farmer John最终想要最小化周长与面积的比值,他称这是他的冰激凌的“冰周率”。当这个比率较小的时候,冰激凌化得比较慢,因为此时冰激凌单位质量的表面积较小。
输入格式
输入的第一行包含N,以下N行描述了机器的生产结果。其中至少出现一个'#'字符。
输出格式
输出一行,包含两个空格分隔的整数,第一个数为最大的冰激凌球的面积,第二个数为它的周长。如果多个冰激凌球并列面积最大,输出其中周长最小的那一个的信息。
样例 #1
样例输入 #1
6
##....
....#.
.#..#.
.#####
...###
....##
样例输出 #1
13 22
题解:
#include<bits/stdc++.h>
using namespace std;
int n,siz,len,anss,ansl;//len与siz为当前联通块周长和大小,anss和ansl为最终联通块大小和周长
char inp;
bool pic[1005][1005],mk[1005][1005];//pic数组存储图,mk数组储存某点是否被遍历过
void dfs(int a,int b){
mk[a][b]=1;
siz++;
for(int i=-1;i<=1;i++)
for(int j=-1;j<=1;j++)
if(abs(i)!=abs(j)){
if(pic[a+i][b+j]==1&&!mk[a+i][b+j])//如果是个未编号节点,递归进入。
dfs(a+i,b+j);
if(pic[a+i][b+j]==0)//如果是个空节点,周长加一
len++;
}
}
int main(){
cin>>n;
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++){
cin>>inp;
if(inp=='#')
pic[i][j]=1;
}
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
if(!mk[i][j]&&pic[i][j]){
siz=0;
len=0;
dfs(i,j);
// cout<<siz<<" "<<len<<'\n';
if(siz>anss){//对大小和周长做最大值处理
anss=siz;
ansl=len;
}
else if(siz==anss)
ansl=min(ansl,len);
}
cout<<anss<<' '<<ansl;
}
这里空空如也
有帮助,赞一个