算法分析
根据题目描述
-
1、没有比它高的叫山峰
-
2、没有比它矮的叫山谷
-
3、还存在又比它高,又比它矮的不算山峰也不算山谷
步骤
-
找到高度一致的连通块,若该连通块周围
-
没有存在比它高的则该连通块叫山峰
-
没有存在比它矮的则该连通块叫山谷
-
时间复杂度 $O(n^2)$
参考文献
算法提高课
Java 代码
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.LinkedList;
import java.util.Queue;
public class Main {
static int N = 1010;
static int n;
static boolean has_higher;
static boolean has_lower;
static int[][] g = new int[N][N];
static boolean[][] st = new boolean[N][N];
static void bfs(int x,int y)
{
Queue<PIIs> q = new LinkedList<PIIs>();
q.add(new PIIs(x,y));
st[x][y] = true;
while(!q.isEmpty())
{
PIIs t = q.poll();
for(int i = t.x - 1;i <= t.x + 1;i ++)
{
for(int j = t.y - 1;j <= t.y + 1;j ++)
{
if(i == t.x && j == t.y) continue;
if(i < 0 || i >= n || j < 0 || j >= n) continue;
/*if(st[i][j]) continue;*/
if(g[i][j] != g[t.x][t.y])
{
if(g[i][j] > g[t.x][t.y]) has_higher = true;
else has_lower = true;
}
else if(!st[i][j])
{
q.add(new PIIs(i,j));
st[i][j] = true;
}
}
}
}
}
public static void main(String[] args) throws IOException {
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
n = Integer.parseInt(reader.readLine().trim());
for(int i = 0;i < n;i ++)
{
String[] s1 = reader.readLine().split(" ");
for(int j = 0;j < n;j ++)
{
g[i][j] = Integer.parseInt(s1[j]);
}
}
int peak = 0, valley = 0;
for(int i = 0;i < n;i ++)
{
for(int j = 0;j < n;j ++)
{
if(!st[i][j])
{
has_higher = false;
has_lower = false;
bfs(i,j);
if(!has_higher) peak ++;
if(!has_lower) valley ++;
}
}
}
System.out.println(peak + " " + valley);
}
}
class PIIs
{
public int x;
public int y;
public PIIs(int x,int y)
{
this.x = x;
this.y = y;
}
}
if(st[i][j]) continue;
这句为啥注释掉?
如果提前加了st[i][j] == true的话,不能与之前标记过的的山脉判断高度了
你好,对你这句话似懂非懂,我有点象不太明白,可以详细说下嘛,为什么不在这里加入
st[i][j] == true
dfs为什么会超时呀
不超
我感觉是语言的问题。。Java不知道为什么
暂时没有看到dfs能过这题的java代码,dfs会显示TLE。我个人分析是dfs会爆栈,例如n=1000并且每个格子的高度w都相同时,栈的层数会来到$10^6$级别,我个人电脑测试是爆栈的。但是y总告诉我,如果java爆栈是RE或者SF,我也挺疑惑的。
java确实很容易爆栈。