【YbtOJ高效進階 廣搜-2】山峰和山谷
阿新 • • 發佈:2021-01-21
小目錄
連結
題目描述
給定一個 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;
}