题意:题意坑爹。问符合条件的的山顶个数
分析:降序排序后从每个点出发,假设为山顶,如果四周的点的高度>h – d那么可以走,如果走到已经走过的点且染色信息(山顶高度)不匹配那么就不是山顶。重点在于就算知道不是山顶也要染色完。
#include <bits/stdc++.h> using namespace std; const int N = 5e2 + 5; const int INF = 0x3f3f3f3f; int h, w, d; struct Point { int x, y, z; Point() {} Point(int x, int y, int z) : x (x), y (y), z (z) {} bool operator < (const Point &r) const { return z > r.z; } }; int dx[4] = {-1, 1, 0, 0}; int dy[4] = {0, 0, -1, 1}; vector<Point> ps; int mat[N][N]; int peak[N][N]; bool vis[N][N]; bool judge(int x, int y, int az) { if (x < 1 || x > h || y < 1 || y > w || mat[x][y] <= az - d) return false; else return true; } int BFS(Point &a) { if (vis[a.x][a.y]) return 0; vis[a.x][a.y] = true; peak[a.x][a.y] = a.z; int cnt = 1; bool flag = true; queue<Point> que; que.push (a); while (!que.empty ()) { Point r = que.front (); que.pop (); for (int i=0; i<4; ++i) { int tx = r.x + dx[i]; int ty = r.y + dy[i]; if (!judge (tx, ty, a.z)) continue; if (vis[tx][ty]) { if (peak[tx][ty] != a.z) { flag = false; } continue; } vis[tx][ty] = true; peak[tx][ty] = a.z; que.push (Point (tx, ty, mat[tx][ty])); if (mat[tx][ty] == a.z) cnt++; } } if (!flag) cnt = 0; return cnt; } int run(void) { memset (vis, false, sizeof (vis)); memset (peak, 0, sizeof (peak)); int ret = 0; for (int i=0; i<ps.size (); ++i) { ret += BFS (ps[i]); } return ret; } int main(void) { int T; scanf ("%d", &T); while (T--) { scanf ("%d%d%d", &h, &w, &d); ps.clear (); for (int i=1; i<=h; ++i) { for (int j=1; j<=w; ++j) { scanf ("%d", &mat[i][j]); ps.push_back (Point (i, j, mat[i][j])); } } sort (ps.begin (), ps.end ()); printf ("%d\n", run ()); } return 0; }