- 101. 孤岛的总面积
注意设置visited和sum的位置,在dfs的for循环之前就不用在main函数中进入dfs时设置
#include <iostream>
#include <list>
#include <queue>
#include <vector>
using namespace std;
int dir[4][2] = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};
void dfs(vector<vector<int>> &grid, vector<vector<bool>> &visited, int i, int j,
int &sum) {
int n = grid.size();
int m = grid[0].size();
visited[i][j] = true;
sum++;
for (auto d : dir) {
int next_i = i + d[0];
int next_j = j + d[1];
if (next_i < 0 || next_i >= n || next_j < 0 || next_j >= m) {
continue;
}
if (!visited[next_i][next_j] && grid[next_i][next_j] == 1) {
dfs(grid, visited, next_i, next_j, sum);
}
}
}
int main() {
int n = 0, m = 0;
cin >> n >> m;
vector<vector<int>> grid(n, vector<int>(m, 0));
int value = 0;
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
cin >> value;
grid[i][j] = value;
}
}
int result = 0;
vector<vector<bool>> visited(n, vector<bool>(m, false));
for (int i = 0; i < n; i++) {
if (!visited[i][0] && grid[i][0] == 1) {
dfs(grid, visited, i, 0, result);
}
if (!visited[i][m - 1] && grid[i][m - 1] == 1) {
dfs(grid, visited, i, m - 1, result);
}
}
for (int j = 0; j < m; j++) {
if (!visited[0][j] && grid[0][j] == 1) {
dfs(grid, visited, 0, j, result);
}
if (!visited[n - 1][j] && grid[n - 1][j] == 1) {
dfs(grid, visited, n - 1, j, result);
}
}
result = 0;
for (int i = 1; i < n; i++) {
for (int j = 1; j < m; j++) {
if (!visited[i][j] && grid[i][j] == 1) {
dfs(grid, visited, i, j, result);
}
}
}
cout << result << endl;
return 0;
}
- [102. 沉没孤岛]](kamacoder.com/problempage…)
和101. 孤岛的总面积类似,不过我们可以将边缘岛屿赋特殊值,然后再将特殊值改回1,将1变为0,这样就相当于将孤岛”沉没“了,而不必再设置visited数组
#include<iostream>
#include<vector>
#include<list>
#include<queue>
using namespace std;
int dir[4][2] = { {-1, 0}, {1, 0}, {0, -1}, {0, 1} };
void dfs(vector<vector<int>>& grid, int x, int y)
{
grid[x][y] = 2;
for (int i = 0; i < 4; i++) {
int next_x = x + dir[i][0];
int next_y = y + dir[i][1];
if (next_x < 0 || next_x >= grid.size() || next_y < 0 || next_y >= grid[0].size()) {
continue;
}
if (grid[next_x][next_y] == 0 || grid[next_x][next_y] == 2) {
continue;
}
dfs(grid, next_x, next_y);
}
}
int main()
{
int n = 0, m = 0;
cin >> n >> m;
vector<vector<int>> grid(n, vector<int>(m, 0));
int value = 0;
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
cin >> value;
grid[i][j] = value;
}
}
int result = 0;
vector<vector<bool>> visited(n, vector<bool>(m, false));
for (int i = 0; i < n; i++) {
if (grid[i][0] == 1) {
dfs(grid, i, 0);
}
if (grid[i][m - 1] == 1) {
dfs(grid, i, m - 1);
}
}
for (int j = 0; j < m; j++) {
if (grid[0][j] == 1) {
dfs(grid, 0, j);
}
if (grid[n - 1][j] == 1) {
dfs(grid, n - 1, j);
}
}
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
if (grid[i][j] == 1) {
grid[i][j] = 0;
}
if (grid[i][j] == 2) {
grid[i][j] = 1;
}
}
}
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
cout << grid[i][j] << " ";
}
cout<<endl;
}
return 0;
}
- [103. 高山流水]](kamacoder.com/problempage…)
可以反过来想,不是找能符合要求的点,而是从边界开始,看逆过来能走到那些节点,两边都能走到的节点就是符合要求的点
#include <iostream>
#include <list>
#include <queue>
#include <vector>
using namespace std;
int dir[4][2] = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};
void dfs(vector<vector<int>> &grid, vector<vector<bool>>& visited, int x,
int y) {
if (visited[x][y])
return;
visited[x][y] = true;
for (int i = 0; i < 4; i++) {
int next_x = x + dir[i][0];
int next_y = y + dir[i][1];
if (next_x < 0 || next_x >= grid.size() || next_y < 0 ||
next_y >= grid[0].size()) {
continue;
}
if (grid[x][y] <= grid[next_x][next_y] && !visited[next_x][next_y]) {
dfs(grid, visited, next_x, next_y);
}
}
}
int main() {
int n = 0, m = 0;
cin >> n >> m;
vector<vector<int>> grid(n, vector<int>(m, 0));
int value = 0;
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
cin >> value;
grid[i][j] = value;
}
}
int result = 0;
vector<vector<bool>> firstVisited(n, vector<bool>(m, false));
vector<vector<bool>> secondVisited(n, vector<bool>(m, false));
for (int i = 0; i < n; i++) {
dfs(grid, firstVisited, i, 0);
dfs(grid, secondVisited, i, m - 1);
}
for (int j = 0; j < m; j++) {
dfs(grid, firstVisited, 0, j);
dfs(grid, secondVisited, n - 1, j);
}
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
if (firstVisited[i][j] && secondVisited[i][j]) {
cout << i << " " << j << endl;
}
}
}
return 0;
}
- 104. 建造最大岛屿
先遍历岛屿保存,再检查每一个海水点的上下左右是否有未加入的岛屿
#include <iostream>
#include <vector>
#include <unordered_set>
#include <unordered_map>
using namespace std;
int n, m;
int count;
int dir[4][2] = {0, 1, 1, 0, -1, 0, 0, -1};
void dfs(vector<vector<int>>& grid, vector<vector<bool>>& visited, int x, int y, int mark) {
if (visited[x][y] || grid[x][y] == 0) return;
visited[x][y] = true;
grid[x][y] = mark;
count++;
for (int i = 0; i < 4; i++) {
int nextx = x + dir[i][0];
int nexty = y + dir[i][1];
if (nextx < 0 || nextx >= n || nexty < 0 || nexty >= m) continue;
dfs(grid, visited, nextx, nexty, mark);
}
}
int main() {
cin >> n >> m;
vector<vector<int>> grid(n, vector<int>(m, 0));
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
cin >> grid[i][j];
}
}
vector<vector<bool>> visited(n, vector<bool>(m, false));
unordered_map<int ,int> gridNum;
int mark = 2;
bool isAllGrid = true;
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
if (grid[i][j] == 0) isAllGrid = false;
if (!visited[i][j] && grid[i][j] == 1) {
count = 0;
dfs(grid, visited, i, j, mark);
gridNum[mark] = count;
mark++;
}
}
}
if (isAllGrid) {
cout << n * m << endl;
return 0;
}
int result = 0;
unordered_set<int> visitedGrid;
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
count = 1;
visitedGrid.clear();
if (grid[i][j] == 0) {
for (int k = 0; k < 4; k++) {
int neari = i + dir[k][1];
int nearj = j + dir[k][0];
if (neari < 0 || neari >= n || nearj < 0 || nearj >= m) continue;
if (visitedGrid.count(grid[neari][nearj])) continue;
count += gridNum[grid[neari][nearj]];
visitedGrid.insert(grid[neari][nearj]);
}
}
result = max(result, count);
}
}
cout << result << endl;
}
```# 算法训练1-day43-图论