TZOJ 5279 马拉松比赛(广搜)

时间:2023-03-09 16:33:27
TZOJ 5279 马拉松比赛(广搜)

描述

有一块矩形的海域,其中有陆地也有海洋,这块海域是CSUFT_ACM集训队的训练基地,这一天,昌神说要集训队的队员不能总是训练,于是昌神提出了中南林ACM集训队第一场环陆马拉松比赛,顾名思义就是围绕着陆地的边缘跑步。现在昌神给你出了个问题:这个比赛最多需要跑多少距离。

注意,这块海域上可能有多块陆地,比赛的场地可能设在任何一块陆地上。

输入

多组输入,每组输入第一行给出两个数字R,C(1 ≤ R, C ≤ 50)。表示这组输入的01矩阵的行数和列数,接下来R行每行输入C个数字(0表示海水,1表示陆地),上下左右相连的陆地算作一块整的陆地。每个0或者1表示一个边长为1正方形。输入保证至少有一块陆地。

TZOJ 5279 马拉松比赛(广搜)

输出

输出陆地周长的最大值。里面的边长也要算在内,例如上图中有四块陆地,最长周长是12 + 4=16。第二长的周长是8,最小的周长是4。

样例输入

1 1
1
6 5
01110
01010
01110
00000
01010
10011

样例输出

4
16

题意

如上

题解

广搜,判断1的点四周,为0边长+1,为1和2不管

已经搜索过的点标记为2不和上面冲突

代码

 #include<stdio.h>
#include<queue>
using namespace std; struct point{int x,y;};
int n,m,maxx;
char a[][];
int dx[]={-,,,};
int dy[]={,,-,}; int bj(int x,int y)//边界
{
if(x>=&&x<n&&y>=&&y<m)
return ;
return ;
} int check(int x,int y)//1四周,如果是0边+1
{
int xx,yy,sum=;
for(int i=;i<;i++)
{
xx=x+dx[i];
yy=y+dy[i];
if(bj(xx,yy))
{
if(a[xx][yy]=='')
sum++;
}
else
sum++;
}
return sum;
} void bfs(int x,int y)
{
queue<point> qu;
point h,t; int sum=;//一块的总周长
h.x=x;h.y=y;
sum+=check(h.x,h.y);
a[h.x][h.y]='';
qu.push(h); while(!qu.empty())
{
h=qu.front();
qu.pop();
for(int i=;i<;i++)
{
t.x=h.x+dx[i];
t.y=h.y+dy[i];
if(bj(t.x,t.y)&&a[t.x][t.y]=='')
{
sum+=check(t.x,t.y);
a[t.x][t.y]='';//这里标记为2,如果标记为0的话算周长会多算
qu.push(t);
}
}
}
if(sum>maxx)
maxx=sum;
}
int main()
{
while(scanf("%d%d",&n,&m)!=EOF)
{
maxx=;
getchar();
for(int i=;i<n;i++)
gets(a[i]);
for(int i=;i<n;i++)
for(int j=;j<m;j++)
if(a[i][j]=='')
bfs(i,j);
printf("%d\n",maxx);
}
return ;
}