【题目描述】
给定一个 n×n 的网格状地图,每个方格 (i,j)有一个高度 wij 。如果两个方格有公共顶点,则它们是相邻的。
定义山峰和山谷如下:
均由地图上的一个连通块组成;
所有方格高度都相同;
周围的方格(即不属于山峰或山谷但与山峰或山谷相邻的格子)高度均大于山谷的高度,或小于山峰的高度。
求地图内山峰和山谷的数量。特别地,如果整个地图方格的高度均相同,则整个地图既是一个山谷,也是一个山峰。【输入】
第一行一个整数n(2≤n≤1000),表示地图的大小。
接下来 n 行每行 n 个整数表示地图。第 i 行有 n 个整数 wi1,wi2,…,win(0≤wij≤1000000000),表示地图第
i 行格子的高度。【输出】
输出一行两个整数,分别表示山峰和山谷的数量。
【输入样例】
输入样例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输入样例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【输出样例】
输出样例1:
2 1
样例解释:
输出样例2:
3 3
样例解释:
思路
按顺序对地图进行遍历,用广搜找每个结点的连通区域(即数字相同的区域),默认每个区域既是山峰又是山谷,在广搜过程中如果邻近结点(可以是已访问的结点)大于或小于该结点则取消这个区域的山峰或山谷标志,如果相等(只能是未访问的结点)则加入队列中继续广搜,如果山峰山谷标志都已取消则提前结束广搜
代码
import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;
public class Main {
static int[][] map;
static boolean[][] visit;
static int[][] move = {{-1,-1},{0,-1},{1,-1},{-1,0},{1,0},{-1,1},{0,1},{1,1}};
static int n;
static boolean hight,low;
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
n = in.nextInt();
map = new int[n][n];
visit = new boolean[n][n];
for(int i=0;i<n;i++) {
for(int j=0;j<n;j++) {
map[i][j] = in.nextInt();
}
}
int hightNum=0,lowNum=0;
for(int i=0;i<n;i++) {
for(int j=0;j<n;j++) {
if(!visit[i][j]) {
hight=true;low=true;
BFS(i,j);
if(hight)
hightNum++;
if(low)
lowNum++;
}
}
}
System.out.print(hightNum + " " + lowNum);
}
public static void BFS(int x,int y) {
Queue<Node> queue = new LinkedList<Node>();
Node start = new Node(x,y);
queue.offer(start);
visit[x][y]=true;
while(!queue.isEmpty()) {
Node next = queue.poll();
for(int i=0;i<8;i++) {
if(!hight && !low)
return;
x=next.x+move[i][0];
y=next.y+move[i][1];
if(x>=0 && x<n && y>=0 && y<n) {
if(map[x][y]<map[next.x][next.y]) {
low=false;
}
else if(map[x][y]>map[next.x][next.y]){
hight=false;
}
else if(!visit[x][y]){
queue.offer(new Node(x,y));
visit[x][y]=true;
}
}
}
}
}
}
class Node{
int x;
int y;
Node(int x,int y){
this.x=x;
this.y=y;
}
}