【ybtoj 高效进阶 1.5】 【广搜】 山峰和山谷
题目
解题思路
广搜找连通块
判断这个连通块周围一圈是否全部小于或大于ta
全部小于则是山峰
全部大于则是山谷
最后输出山峰和山谷的个数
代码
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
struct lzf{
int x,y;
}q[1000050];
int n,tz,ansmi,ansma;
int a[1005][1005],p[1005][1005],vis[1005][1005];
int fx[9]={0,1,1,0,-1,-1,-1,0,1},fy[9]={0,0,1,1,1,0,-1,-1,-1};
void bfs(int x,int y)
{
int h=0,t=1,mi=1,ma=1;
q[t].x=x,q[t].y=y;
vis[x][y]=1;
p[x][y]=1;
do{
h++;
for (int i=1;i<=8;i++)
{
int xx=q[h].x+fx[i],yy=q[h].y+fy[i];
if (xx>0&&xx<=n&&yy>0&&yy<=n) //判断是否能走
if (a[xx][yy]!=a[x][y]) //不是连通块内部,是周围的
{
if (a[x][y]>a[xx][yy]) mi=0;
if (a[x][y]<a[xx][yy]) ma=0; //记录状态
}
else if (!p[xx][yy]) //是否走过
{
q[++t].x=xx;
q[t].y=yy;
p[xx][yy]=1;
}
}
}while (h<t);
if (!mi&&ma) ansmi++;
if (!ma&&mi) ansma++; //统计个数
}
int main()
{
scanf("%d",&n);
for (int i=1;i<=n;i++)
for (int j=1;j<=n;j++)
scanf("%d",&a[i][j]);
for (int i=1;i<=n;i++)
for (int j=1;j<=n;j++)
if (!p[i][j])
{
p[i][j]=1;
bfs(i,j);
tz++;
}
if (tz==1)
printf("1 1\n"); //全部一样
else printf("%d %d\n",ansmi,ansma);
return 0;
}