题目大意
输入一个n*n的矩阵,每一个权值相等的连通块,有:
- 当该连通块周围全都比它小,为山峰
- 当该连通块周围全都比它大,为山谷
- 如果全地图只是一个连通块,既是山峰也是山谷
- 否则,啥也不是
求山峰山谷个数.
思路
对于每一个连通块,求它是山峰还是山谷
code:
#include<iostream>
#include<queue>
using namespace std;
int q[8][2]={{0,1},{-1,0},{1,0},{0,-1},{-1,1},{1,-1},{1,1},{-1,-1}};
bool o1,o2;
int n,s1,s2;
struct f{
int x,y;
} wj,ak,ioi;
queue<f> p,p2;
int a[1001][1001],w;
bool velix[1001][1001];
void bfs(int x,int y)
{
p=p2;
o1=o2=0;
w=a[x][y];
velix[x][y]=1;
wj.x=x,wj.y=y;
p.push(wj);
while (p.size())
{
ak=p.front();
p.pop();
for (int i=0;i<8;i++)
{
int dx=ak.x+q[i][0],dy=ak.y+q[i][1];
if (dx<1||dy<1||dx>n||dy>n) continue;
if (a[dx][dy]==w&&velix[dx][dy]==0)
{
velix[dx][dy]=1;
ioi.x=dx,ioi.y=dy;
p.push(ioi);
}
if (a[dx][dy]>w)
{
o1=1;
}
if (a[dx][dy]<w) o2=1;
}
}
if (o1==0&&o2==0) s1++,s2++;
if (o1==1&&o2==0) s1++;
if (o1==0&&o2==1) s2++;
return;
}
int main()
{
cin>>n;
for (int i=1;i<=n;i++)
{
for (int j=1;j<=n;j++) cin>>a[i][j];
}
for (int i=1;i<=n;i++)
{
for (int j=1;j<=n;j++)
{
if (velix[i][j]==0)
{
bfs(i,j);
}
}
}
cout<<s2<<' '<<s1<<endl;
return 0;
}