此代码中共有三个函数也分为三个步骤,一个是b函数用来判断当前格子周围的八连通中雷的数量,当然如果当前格子是雷就跳过,c函数用于计算当前格子是否满足3bv的条件,如果满足,则ans++,还有就是如果是空格,则用一个bfs函数将与其联通的八连通的vis都变为1,代表已经访问过,说明他们是一个空,防止重复计算。 #include <bits/stdc++.h> using namespace std; int n, m; int a[1005][1005]; bool p[1005][1005]; int ans; int vis[1005][1005]; struct point{ int x, y; }; int dx[8]={-1,-1,-1,0,0,1,1,1},dy[8]={-1,0,1,-1,1,-1,0,1}; void bfs(int x, int y) { queue<point> q; q.push({x, y}); while (!q.empty()) { point f = q.front(); q.pop(); vis[f.x][f.y] = 1; for (int k = 0; k < 8; ++k) { int x1 = f.x + dx[k], y1 = f.y + dy[k]; if (x1 > 0 && x1 <= n && y1 > 0 && y1 <= m) { if (vis[x1][y1] == 0) // 没有被访问过 { if (a[x1][y1] == 0) // 并且是空格 { vis[x1][y1] = 1; q.push({x1,y1}); } } } } } } void b() { for (int i = 1; i <= n; ++i) { for (int j = 1; j <= m; ++j) { if (p[i][j]) continue; else { for (int k = 0; k < 8; ++k) { int x = i + dx[k], y = j + dy[k]; if (p[x][y]) { a[i][j]++; } } } } } } void c() { for (int i = 1; i <= n; ++i) { for (int j = 1; j <= m; ++j) { if (p[i][j]) // 是雷就跳过 continue; else // 不是雷进行判断 { if (a[i][j] != 0) // 不是空格 { int flag = 0; for (int k = 0; k < 8; ++k) { int x = i + dx[k], y = j + dy[k]; if (x > 0 && x <= n && y > 0 && y <= m) { if (a[x][y] == 0) { flag = 1; // 为1代表周围有空格 } } } if (flag == 0) // 没空格ans++ ans++; } else if (vis[i][j] == 0) // 是空格 { ans++; bfs(i,j); } } } } } int main() { cin >> n >> m; for (int i = 1; i <= m+1 ; ++i) { a[1][i] = 0; a[n+1][i] = 0; } for (int i = 1; i <= n+1 ; ++i) { a[i][1] = 0; a[i][m+1] = 0; } for (int i = 1; i <= n; ++i) { for (int j = 1; j <= m; ++j) { cin >> a[i][j]; if (a[i][j] == 1) p[i][j] = true; } } b(); c(); cout << ans; return 0; }
P4961 小埋与扫雷(bfs解法)
最新推荐文章于 2024-06-21 17:14:10 发布