题目描述
FGD小朋友特别喜欢爬山,在爬山的时候他就在研究山峰和山谷。
为了能够对旅程有一个安排,他想知道山峰和山谷的数量。
给定一个地图,为FGD想要旅行的区域,地图被分为 n×n 的网格,每个格子 (i,j) 的高度 w(i,j) 是给定的。
若两个格子有公共顶点,那么它们就是相邻的格子,如与 (i,j) 相邻的格子有(i−1,j−1),(i−1,j),(i−1,j+1),(i,j−1),(i,j+1),(i+1,j−1),(i+1,j),(i+1,j+1)。
我们定义一个格子的集合 S 为山峰(山谷)当且仅当:
S 的所有格子都有相同的高度。
S 的所有格子都连通。
对于 s 属于 S,与 s 相邻的 s′ 不属于 S,都有 ws>ws′(山峰),或者 ws<ws′(山谷)。
如果周围不存在相邻区域,则同时将其视为山峰和山谷。
你的任务是,对于给定的地图,求出山峰和山谷的数量,如果所有格子都有相同的高度,那么整个地图即是山峰,又是山谷。
输入格式
第一行包含一个正整数 n,表示地图的大小。
接下来一个 n×n 的矩阵,表示地图上每个格子的高度 w。
输出格式
共一行,包含两个整数,表示山峰和山谷的数量。
数据范围
1≤n≤1000,
0≤w≤109
样例
输入样例1:
5
8 8 8 7 7
7 7 8 8 7
7 7 7 7 7
7 8 8 7 8
7 8 8 8 8
输出样例1:
2 1
输入样例2:
5
5 7 8 3 1
5 5 7 6 6
6 6 6 2 8
5 7 2 5 8
7 1 0 1 7
输出样例2:
3 3
算法1
(暴力枚举) $O(n^2)$
抽象一下题意就是,山峰是在他周围不存在任何一个比他高的数值,那么他就是山峰,山谷即使周围不存在任何一个比他低的数值(一个山可能即时山谷,也是山峰),知道题意之后跑一下flood fill就可以了,还有就是这题的世间卡的比较紧,用scanf读入,printf输出,队列用自己手写的队列。~。~
C++ 代码
#include<iostream>
#include<cstring>
#include<algorithm>
#define pii pair<int,int>
using namespace std;
const int N = 1010 , M = N * N;
int g[N][N];
pii q[M];
int dx[8]={-1,-1,-1,0,0,1,1,1},dy[8]={-1,0,1,-1,1,-1,0,1};
bool st[N][N];
int n;
bool higher,lower;
void bfs(int x,int y){
int tt=0,hh=0;
q[0]={x,y};
st[x][y]=true;
while(tt>=hh)
{
pii t=q[hh++];
for(int i=0;i<8;i++)
{
int a=t.first+dx[i],b=t.second+dy[i];
if(a>=0&&a<n&&b>=0&&b<n)
{
if(g[a][b]!=g[t.first][t.second])
{
if(g[a][b]>g[t.first][t.second]) higher=true;
else lower=true;
}
else if(!st[a][b])
{
st[a][b]=true;
q[++tt]={a,b};
}
}
}
}
}
int main(){
//freopen("data.in","r",stdin);
//freopen("data.out","w",stdout);
scanf("%d",&n);
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
scanf("%d",&g[i][j]);
int valley = 0,peak = 0;
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
if(!st[i][j])
{
higher=false;
lower=false;
bfs(i,j);
if(!higher) peak++;
if(!lower) valley++;
}
printf("%d %d\n",peak,valley);
return 0;
}
22年看图图佬19年刷过的题
dfs为什么会超时呀
可能是代码问题
楼主代码没问题,我写了深度优先遍历超时了,dfs时间复杂度怎么算qwq
dfs和bfs时间复杂度一样的,我说的是你dfs可能代码写的有问题
常数可能超了