1. 程式人生 > 其它 >【YbtOJ高效進階 廣搜-2】山峰和山谷

【YbtOJ高效進階 廣搜-2】山峰和山谷

技術標籤:bfs廣搜bfs

小目錄

連結

YbtOJ高效進階 廣搜-2

題目描述

給定一個 n*n 的網格狀地圖,每個方格 (i,j) 有一個高度 w i , j w_{i,j} wi,j 。如果兩個方格有公共頂點,則它們是相鄰的。

定義山峰山谷如下:

均由地圖上的一個聯通塊組成。
所有方格高度都相同。
周圍的方格(即不屬於山峰或山谷但與山峰或山谷相鄰的格子)高度均大於山谷的高度,或小於山峰的高度。
求地圖內山峰和山谷的數量。特別的,如果整個地圖方格的高度均相同,則整個地圖即是一個山谷,也是一個山峰。

有與 (x,y) 有公共頂點的點集是(x,y) 的八連通,直播時口誤

樣例輸入

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

思路

每次找一個新的沒訪問過的點,然後和相鄰的點去進行高度的對比,
1.如果當前連通塊的高度比找到的這個點的高度大,那就是山峰
2.如果小,那就是山谷
3.如果有大有小,那就啥也不是
4.如果最後找完了, 都沒有大小關係,那就既是山谷,又是山峰

程式碼

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include
<queue>
using namespace std; int n, flag1, flag2, ans1, ans2; int w[1005][1005], vis[1005][1005]; int dx[8] = {0, 0, 1, 1, -1, -1, 1, -1}; int dy[8] = {1, -1, 0, -1, 1, 0, 1, -1}; bool check(int x, int y) { if(x < 1 || x > n || y < 1 || y > n) return 0; return 1; } void bfs(int x, int y) {
int val = w[x][y]; queue<pair<int, int> >Q; Q.push(make_pair(x, y)); bool flag1 = flag2 = 0; while(Q.size()) { pair<int, int> tot = Q.front(); Q.pop(); int xx = tot.first, yy = tot.second; for(int i = 0; i < 8; ++i) { int nx = xx + dx[i], ny = yy + dy[i]; if(check(nx, ny)) { if(w[nx][ny] == val) { if(!vis[nx][ny]) { vis[nx][ny] = 1; Q.push(make_pair(nx, ny)); } } else { if(w[nx][ny] < val) flag1 = 1; if(w[nx][ny] > val) flag2 = 1; } } } } if(!flag1 && !flag2) ans1++, ans2++;//對應情況4 if(flag1 && !flag2) ans1++;//對應情況2 if(!flag1 && flag2) ans2++;//對應情況1 } int main() { scanf("%d", &n); for(int i = 1; i <= n; ++i) for(int j = 1; j <= n; ++j) scanf("%d", &w[i][j]); for(int i = 1; i <= n; ++i) for(int j = 1; j <= n; ++j) if(!vis[i][j]) bfs(i, j); printf("%d %d", ans1, ans2); return 0; }