水平竖直和斜方向是一个点数值的比较对象,一共八个。相同的的高度可以连接在一起,形成山谷、山峰或者啥都不是。如果对于一个连接在一起的一块地方,其任意一点周围高度都比他小,那他就是山峰;反之为山谷;有大有小啥也不是。
思路bfs。搜索相同高度的点,还要看这个点周围一圈的高度大小:有大的就标记isV意味着是山谷,有小的就表记isR,两者同时为true就啥都不是,都是false就以为着既是山峰又是山谷(题意)。其中任一true而另外不true就意味着是山峰或者山谷,对应的sumR++或sumV++即可。比较重要的是,每次在main里面遍历的时候,要还原isR isV为false。另外java这个语言感觉有点诡异,在我优化之后还是MLE,从52/100变成了65/100,不能过,无奈翻译成了C++语言。
AC代码(由我的java代码翻译而来):#include#include #include #include #include #include #include using namespace std; struct node{ int x,y; node(){x=y=0;} node(int _x,int _y){x=_x;y=_y;} }; int n; int a[1002][1002]; bool visited[1002][1002]; int vec[][2]= {{-1, -1}, {-1, 0}, {-1, 1}, {0, -1}, {0, 1}, {1, -1}, {1, 0}, {1, 1}}; int numR = 0, numV = 0; bool isR, isV; bool isInArea(int i, int j) { return i >= 0 && i < n && j >= 0 && j < n; } void bfs(int i, int j) { queue queue; queue.push(node(i,j)); visited[i][j] = true; while (!queue.empty()) { node fronti = queue.front();queue.pop(); int x = fronti.x; int y = fronti.y; for (int k=0;k<8;k++) { int nx = x + vec[k][0]; int ny = y + vec[k][1]; if (isInArea(nx, ny) && (!visited[nx][ny] || a[nx][ny] != a[i][j])) { if (a[nx][ny] > a[i][j]) isV = true; else if (a[nx][ny] < a[i][j]) isR = true; else if (a[nx][ny] == a[i][j]) { queue.push(node(nx,ny)); visited[nx][ny] = true; } } } } if(!isR&&!isV) { numR++; numV++; } else if (!isR || !isV) { if (isR) numR++; if (isV) numV++; } } int main(){ cin>>n; for (int i = 0; i < n; i++) for (int j = 0; j < n; j++) cin>>a[i][j]; for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { if (!visited[i][j]) { isV = isR = false; bfs(i, j); } } } cout< 不AC的java代码(MLE): import java.io.*; import java.util.*; class Main { static int n; static int[][] a = new int[1002][1002]; static boolean[][] visited = new boolean[1002][1002]; static int[][] vec = {{-1, -1}, {-1, 0}, {-1, 1}, {0, -1}, {0, 1}, {1, -1}, {1, 0}, {1, 1}}; static int numR = 0, numV = 0; static boolean isR, isV; public static void main(String[] args) throws IOException { StreamTokenizer sc = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in))); PrintWriter out = new PrintWriter(new BufferedOutputStream(System.out)); sc.nextToken(); n = (int) sc.nval; for (int i = 0; i < n; i++) for (int j = 0; j < n; j++) { sc.nextToken(); a[i][j] = (int) sc.nval; } for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { if (!visited[i][j]) { isV = isR = false; bfs(i, j); } } } out.print(numR + " " + numV); } static void bfs(int i, int j) { Queuequeue = new LinkedList<>(); queue.offer(new int[]{i, j}); visited[i][j] = true; while (!queue.isEmpty()) { int[] front = queue.poll(); int x = front[0]; int y = front[1]; for (int[] k : vec) { int nx = x + k[0]; int ny = y + k[1]; if (isInArea(nx, ny) && (!visited[nx][ny] || a[nx][ny] != a[i][j])) { if (a[nx][ny] > a[i][j]) isV = true; else if (a[nx][ny] < a[i][j]) isR = true; else if (a[nx][ny] == a[i][j]) { queue.offer(new int[]{nx, ny}); visited[nx][ny] = true; } } } } if (!isR && !isV) { numR++; numV++; } else if (!isR || !isV) { if (isR) numR++; if (isV) numV++; } } static boolean isInArea(int i, int j) { return i >= 0 && i < n && j >= 0 && j < n; } }



