题目描述
给定一个n×n的网格状地图,每个方格(i,j)有一个高度wij。如果两个方格有公共顶点,则它们是相邻的。
定义山峰和山谷如下:
均由地图上的一个连通块组成;
所有方格高度都相同;
周围的方格(即不属于山峰或山谷但与山峰或山谷相邻的格子)高度均大于山谷的高度,或小于山峰的高度。
求地图内山峰和山谷的数量。特别地,如果整个地图方格的高度均相同,则整个地图既是一个山谷,也是一个山峰。
定义山峰和山谷如下:
均由地图上的一个连通块组成;
所有方格高度都相同;
周围的方格(即不属于山峰或山谷但与山峰或山谷相邻的格子)高度均大于山谷的高度,或小于山峰的高度。
求地图内山峰和山谷的数量。特别地,如果整个地图方格的高度均相同,则整个地图既是一个山谷,也是一个山峰。
输入
第一行一个整数n(2≤n≤1000),表示地图的大小。
接下来n行每行n个整数表示地图。第i行有n个整数wi1,wi2,…,win(0≤wij≤1000000000),表示地图第i行格子的高度。
接下来n行每行n个整数表示地图。第i行有n个整数wi1,wi2,…,win(0≤wij≤1000000000),表示地图第i行格子的高度。
输出
输出一行两个整数,分别表示山峰和山谷的数量。
样例输入
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 1
【题解】
其实直接搜索即可,但是BFS时不要看到附近有 比他高 或者比他低就轻易设定为山峰或者山谷。
我们需要做的一件事是找连通块,是八连通块。然后连通块只能单纯比该连通块高或者低,不要出现有高有低的情况。
所以而且连通块找出来之后要全部给标记。
如果这个图都是一个高度需要则输出“1 1”
1 #include2 using namespace std; 3 const int N = 1e3+10; 4 int dir[8][2] ={ 5 {-1,-1} , {-1,0} , {-1,1}, 6 {0,-1} , {0,1}, 7 {1,-1} , {1,0} , {1,1} 8 }; 9 typedef struct Node { 10 int x,y; 11 }Node ; 12 int n,G[N][N],vis[N][N]; 13 int valley,peak; 14 void BFS(int x,int y,int k){ 15 queue Q ; 16 Q.push( Node{x,y} ) ; 17 vis[x][y] = 1 ; 18 bool Large = false , Small = false ; 19 while ( ! Q.empty() ){ 20 //printf("#"); 21 Node cur = Q.front() ; 22 Q.pop(); 23 for(int i=0;i<8;i++){ 24 int tx = cur.x + dir[i][0]; 25 int ty = cur.y + dir[i][1]; 26 if ( !(1 <= tx && tx <= n && 1<=ty && ty <=n ) ) 27 continue ; 28 if ( vis[tx][ty] && G[tx][ty] == k ) 29 continue; 30 if ( G[tx][ty] == k ){ 31 vis[tx][ty] = 1 ; 32 Q.push( (Node) { tx,ty } ) ; 33 }else if ( G[tx][ty] > k ){ 34 Large = true; 35 }else{ 36 Small = true; 37 } 38 } 39 } 40 if ( Large && Small ){ 41 return ; 42 } 43 if ( Large ) valley ++ ; 44 if ( Small ) peak ++; 45 } 46 int main() 47 { 48 scanf("%d",&n); 49 for(int i=1;i<=n;i++){ 50 for(int j=1;j<=n;j++){ 51 scanf("%d",&G[i][j]); 52 } 53 } 54 for(int i=1;i<=n;i++){ 55 for(int j=1;j<=n;j++){ 56 if( vis[i][j] == 0 ) { 57 58 BFS(i,j,G[i][j]); 59 //printf("(%d,%d) Peak %d , valley %d \n",i,j,peak,valley); 60 } 61 62 } 63 } 64 if( peak + valley == 0 ){ 65 printf("1 1\n"); 66 }else{ 67 printf("%d %d\n",peak,valley); 68 } 69 return 0; 70 }