if (!max1adjacent) { // 待感染区域面积为0,说明没有活病毒了或者全部被病毒感染了(其实似乎不用has1 变量即可) break; }
pair<int, int> oneOfThisArea = area2loc[max1adjacent]; ans += loc2wallNum[oneOfThisArea];
// 再次BFS标记此区域病毒为已隔离 // 其他区域扩散
具体BFS方法为:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
queue<pair<int, int>> q; q.push(oneOfThisArea); isInfected[oneOfThisArea.first][oneOfThisArea.second] = 2; while (q.size()) { auto[x, y] = q.front(); q.pop(); for (int d = 0; d < 4; d++) { int tx = x + direction[d][0]; int ty = y + direction[d][1]; if (tx >= 0 && tx < n && ty > 0 && ty < m) { if (isInfected[tx][ty] == 1) { isInfected[tx][ty] = 2; q.push({tx, ty}); } } } }
visited = vector<vector<bool>>(n, vector<bool>(m, false)); for (int x = 0; x < n; x++) { for (int y = 0; y < m; y++) { if (isInfected[x][y] == 1 && !visited[x][y]) { visited[x][y] = true; q.push({x, y}) ; while (q.size()) { auto[x, y] = q.front(); q.pop(); for (int d = 0; d < 4; d++) { int tx = x + direction[d][0]; int ty = y + direction[d][1]; if (tx >= 0 && tx < n && ty >= 0 && ty < m) { if (isInfected[tx][ty] == 0) { // 空地 isInfected[tx][ty] = 1; visited[tx][ty] = true; // 防止继续感染拓展 } elseif (isInfected[tx][ty] == 1 && !visited[tx][ty]) { // 还是病毒 && 还未被处理过 visited[tx][ty] = true; q.push({tx, ty}); } } } } } } }
方法二
其实这次就没必要再搜索了
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
visited = vector<vector<bool>>(n, vector<bool>(m, false)); for (int x = 0; x < n; x++) { for (int y = 0; y < m; y++) { if (isInfected[x][y] == 1 && !visited[x][y]) { visited[x][y] = true; for (int d = 0; d < 4; d++) { int tx = x + direction[d][0]; int ty = y + direction[d][1]; if (tx >= 0 && tx < n && ty >= 0 && ty < m) { if (isInfected[tx][ty] == 0) { isInfected[tx][ty] = 1; visited[tx][ty] = true; } } } } } }
classSolution { private: int ans = 0; public: intcontainVirus(vector<vector<int>>& isInfected){ int n = isInfected.size(); int m = isInfected[0].size(); while (true) { bool has1 = false;
int max1adjacent = 0; // 活病毒的最大相邻待感染区域的大小 map<int, pair<int, int>> area2loc; // [<待感染区域的面积, 其中一个活病毒的坐标>] map<pair<int, int>, int> loc2wallNum; // [<活病毒的坐标, 需要添加的墙的数量>] vector<vector<bool>> visited(n, vector<bool>(m, false)); // 哪个区域被遍历过了 for (int i = 0; i < n; i++) { for (int j = 0; j < m; j++) { if (isInfected[i][j] == 1 && !visited[i][j]) { // 这是一个活病毒的位置 && 这个区域还没有被遍历过 has1 = true; visited[i][j] = true; pair<int, int> oneOfThisArea = {i, j}; int thisAdjacent = 0; // 这个待感染区域的大小 int thisWallNum = 0; // 控制这个区域的话,需要安装隔离墙的数量 set<pair<int, int>> counted; // 已经统计过的待感染区域 // 注意不能通过将visited标记为true的方式来判断某个待感染区域是否被统计过,因为待感染区域对于不同的病毒块互不影响
queue<pair<int, int>> q; q.push({i, j}); while (q.size()) { auto[x, y] = q.front(); q.pop(); for (int d = 0; d < 4; d++) { int tx = x + direction[d][0]; int ty = y + direction[d][1]; if (tx >= 0 && tx < n && ty >= 0 && ty < m) { // 下一个单元在合法范围内 if (isInfected[tx][ty] == 1 && !visited[tx][ty]) { // 下一个单元是未被标记的病毒 visited[tx][ty] = true; q.push({tx, ty}); } elseif (isInfected[tx][ty] == 0) { // 下一个单元格是待感染区域 thisWallNum++; // 不论这个待感染区域是否被统计过,都要安装隔离墙(区域只统计一次,但隔离墙最多要安装4面) if (!counted.count({tx, ty})) { // 这个区域还未被统计过 counted.insert({tx, ty}); thisAdjacent++; } } } } }
queue<pair<int, int>> q; q.push(oneOfThisArea); isInfected[oneOfThisArea.first][oneOfThisArea.second] = 2; while (q.size()) { auto[x, y] = q.front(); q.pop(); for (int d = 0; d < 4; d++) { int tx = x + direction[d][0]; int ty = y + direction[d][1]; if (tx >= 0 && tx < n && ty >= 0 && ty < m) { if (isInfected[tx][ty] == 1) { isInfected[tx][ty] = 2; q.push({tx, ty}); } } } }
visited = vector<vector<bool>>(n, vector<bool>(m, false)); for (int x = 0; x < n; x++) { for (int y = 0; y < m; y++) { if (isInfected[x][y] == 1 && !visited[x][y]) { visited[x][y] = true; for (int d = 0; d < 4; d++) { int tx = x + direction[d][0]; int ty = y + direction[d][1]; if (tx >= 0 && tx < n && ty >= 0 && ty < m) { if (isInfected[tx][ty] == 0) { isInfected[tx][ty] = 1; visited[tx][ty] = true; } } } } } }