#include<iostream>#include<cstring>#include<vector>usingnamespace std;
constint N = 55;
int arr[N][N];
bool used[N][N];
int dir[4][2] = {0, 1, 0, -1, 1, 0, -1, 0};
voiddfs(int x, int y){
for (int i = 0; i < 4; ++i) {
int x_cur = x + dir[i][0];
int y_cur = y + dir[i][1];
if (!used[x_cur][y_cur] && arr[x_cur][y_cur] == 1) {
used[x_cur][y_cur] = true;
dfs(x_cur, y_cur);
}
}
}
intmain(){
int n, m;
int cnt = 0;
cin >> n >> m;
for (int i = 1; i <= n; ++i)
for (int j = 1; j <= m; ++j)
cin >> arr[i][j];
memset(used, false, sizeof used);
for (int i = 1; i <= n; ++i)
for (int j = 1; j <= m; ++j) {
if (!used[i][j] && arr[i][j] == 1) {
used[i][j] = true;
cnt++;
dfs(i, j);
}
}
cout << cnt << endl;
return0;
}
BFS 解法
#include<iostream>#include<vector>#include<queue>usingnamespace std;
int dir[4][2] = {{0, 1}, {0, -1}, {1, 0}, {-1, 0}};
int result = 0;
voidbfs(const vector<vector<int>> &grid, vector<vector<bool>> &used, int n, int m){
queue<pair<int, int>> que;
que.push({n, m});
used[n][m] = true;
while (!que.empty()) {
pair<int, int> cur = que.front();
que.pop();
for (int i = 0; i < 4; ++i) {
int nextY = cur.first + dir[i][0];
int nextX = cur.second + dir[i][1];
if (nextX < 0 || nextX >= grid[0].size() || nextY < 0 || nextY >= grid.size())
continue;
if (grid[nextY][nextX] == 1 && !used[nextY][nextX]) {
used[nextY][nextX] = true;
que.push({nextY, nextX});
}
}
}
}
intmain(){
int n, m;
cin >> n >> m;
vector<vector<int>> grid(n, vector<int>(m, 0));
vector<vector<bool>> used(n, vector<bool>(m, false));
for (int i = 0; i < n; ++i)
for (int j = 0; j < m; ++j)
cin >> grid[i][j];
for (int i = 0; i < n; ++i)
for (int j = 0; j < m; ++j) {
if (grid[i][j] == 1 && !used[i][j]) {
result++;
bfs(grid, used, i, j);
}
}
cout << result << endl;
return0;
}
2、岛屿的面积(dfs)
题目描述
计算岛屿的最大面积。岛屿面积的计算方式为组成岛屿的陆地的总数。
数据范围
1 <= M, N <= 50
#include<iostream>#include<cstring>#include<vector>usingnamespace std;
constint N = 55;
int arr[N][N];
bool used[N][N];
int dir[4][2] = {0, 1, 0, -1, 1, 0, -1, 0};
int cur_area;
int max_area;
voiddfs(int x, int y){
for (int i = 0; i < 4; ++i) {
int x_cur = x + dir[i][0];
int y_cur = y + dir[i][1];
if (!used[x_cur][y_cur] && arr[x_cur][y_cur] == 1) {
used[x_cur][y_cur] = true;
cur_area++;
dfs(x_cur, y_cur);
}
}
}
intmain(){
int n, m;
cin >> n >> m;
for (int i = 1; i <= n; ++i)
for (int j = 1; j <= m; ++j)
cin >> arr[i][j];
memset(used, false, sizeof used);
for (int i = 1; i <= n; ++i)
for (int j = 1; j <= m; ++j) {
if (!used[i][j] && arr[i][j] == 1) {
cur_area = 1;
used[i][j] = true;
dfs(i, j);
max_area = max(max_area, cur_area);
}
}
cout << max_area << endl;
return0;
}
3、孤岛的总面积(dfs)
题目描述
计算所有孤岛的总面积。孤岛是那些位于矩阵内部、所有单元格都不接触边缘的岛屿。
#include<iostream>#include<cstring>usingnamespace std;
constint N = 55;
int arr[N][N];
bool used[N][N];
int n, m;
int dir[4][2] = {1, 0, -1, 0, 0, 1, 0, -1};
voiddfs(int x, int y){
for (int i = 0; i < 4; ++i) {
int cur_x = x + dir[i][0];
int cur_y = y + dir[i][1];
if (cur_x < 0 || cur_x >= m || cur_y < 0 || cur_y >= n)
continue;
if (used[cur_x][cur_y] || arr[cur_x][cur_y] == 0)
continue;
used[cur_x][cur_y] = true;
dfs(cur_x, cur_y);
}
}
intmain(){
cin >> m >> n;
memset(used, false, sizeof used);
for (int i = 0; i < m; ++i)
for (int j = 0; j < n; ++j)
cin >> arr[i][j];
// 清空边界for (int i = 0; i < m; ++i) {
if (used[i][0] || arr[i][0] == 0) continue;
used[i][0] = true;
dfs(i, 0);
}
for (int i = 0; i < m; ++i) {
if (used[i][n - 1] || arr[i][n - 1] == 0) continue;
used[i][n - 1] = true;
dfs(i, n - 1);
}
for (int i = 0; i < n; ++i) {
if (used[0][i] || arr[0][i] == 0) continue;
used[0][i] = true;
dfs(0, i);
}
for (int i = 0; i < n; ++i) {
if (used[m - 1][i] || arr[m - 1][i] == 0) continue;
used[m - 1][i] = true;
dfs(m - 1, i);
}
int cnt = 0;
for (int i = 0; i < m; ++i)
for (int j = 0; j < n; ++j)
if (!used[i][j] && arr[i][j] == 1)
cnt++;
cout << cnt << endl;
return0;
}
4、沉没孤岛(dfs)
题目描述
将所有孤岛'沉没',即将孤岛中的所有陆地单元格(1)转变为水域单元格(0)。
#include<iostream>#include<vector>usingnamespace std;
int dir[4][2] = {{0, 1}, {0, -1}, {1, 0}, {-1, 0}};
voiddfs(const vector<vector<int>> &grid, vector<vector<bool>> &used, int x, int y){
used[x][y] = true;
for (int i = 0; i < 4; ++i) {
int nextX = x + dir[i][0];
int nextY = y + dir[i][1];
if (nextX < 0 || nextX >= grid.size() || nextY < 0 || nextY >= grid[0].size())
continue;
if (grid[nextX][nextY] == 1 && !used[nextX][nextY]) {
used[nextX][nextY] = true;
dfs(grid, used, nextX, nextY);
}
}
}
intmain(){
int n, m;
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>> used(n, vector<bool>(m, false));
for (int i = 0; i < n; ++i) {
if (grid[i][0] && !used[i][0]) dfs(grid, used, i, 0);
if (grid[i][m - 1] && !used[i][m - 1]) dfs(grid, used, i, m - 1);
}
for (int i = 0; i < m; ++i) {
if (grid[0][i] && !used[0][i]) dfs(grid, used, 0, i);
if (grid[n - 1][i] && !used[n - 1][i]) dfs(grid, used, n - 1, i);
}
for (int i = 0; i < n; ++i) {
for (int j = 0; j < m; ++j) {
if (grid[i][j] && used[i][j])
cout << 1 << " ";
else
cout << 0 << " ";
}
cout << endl;
}
return0;
}
5、水流问题
题目描述
确定那些单元格,从这些单元格出发的水可以达到第一组边界和第二组边界。
注意
本题需要建立记忆化搜索,否则会造成无限递归。
#include<iostream>#include<cstring>usingnamespace std;
constint N = 105;
int n, m;
int arr[N][N];
int arr_one[N][N];
int arr_two[N][N];
int dir[4][2] = {1, 0, -1, 0, 0, 1, 0, -1};
voiddfs(int cur_arr[N][N], int flag, int x, int y){
for (int i = 0; i < 4; ++i) {
int cur_x = x + dir[i][0];
int cur_y = y + dir[i][1];
if (cur_x < 0 || cur_x >= n || cur_y < 0 || cur_y >= m)
continue;
if (cur_arr[cur_x][cur_y] != 0)
continue;
if (arr[x][y] <= arr[cur_x][cur_y]) {
cur_arr[cur_x][cur_y] = flag;
dfs(cur_arr, flag, cur_x, cur_y);
}
}
}
intmain(){
cin >> n >> m;
memset(arr_one, 0, sizeof arr_one);
memset(arr_two, 0, sizeof arr_two);
for (int i = 0; i < n; ++i)
for (int j = 0; j < m; ++j)
cin >> arr[i][j];
for (int i = 0; i < n; ++i) {
arr_one[i][0] = 1;
dfs(arr_one, 1, i, 0);
arr_two[i][m - 1] = 2;
dfs(arr_two, 2, i, m - 1);
}
for (int i = 0; i < m; ++i) {
arr_one[0][i] = 1;
dfs(arr_one, 1, 0, i);
arr_two[n - 1][i] = 2;
dfs(arr_two, 2, n - 1, i);
}
for (int i = 0; i < n; ++i)
for (int j = 0; j < m; ++j)
if (arr_one[i][j] == 1 && arr_two[i][j] == 2)
cout << i << " " << j << endl;
return0;
}
6、建造最大岛屿
题目描述
最多可以将矩阵中的一格水变为一块陆地,求执行此操作之后,矩阵中最大的岛屿面积是多少。
#include<iostream>#include<unordered_map>#include<unordered_set>usingnamespace std;
constint N = 55;
int n, m;
int arr[N][N];
int dir[4][2] = {1, 0, -1, 0, 0, 1, 0, -1};
voiddfs(int x, int y, int mark, int &cnt){
if (x < 0 || x >= n || y < 0 || y >= m)
return;
if (arr[x][y] != 1)
return;
cnt++;
arr[x][y] = mark;
for (int i = 0; i < 4; ++i) {
dfs(x + dir[i][0], y + dir[i][1], mark, cnt);
}
}
intmain(){
cin >> n >> m;
for (int i = 0; i < n; ++i)
for (int j = 0; j < m; ++j)
cin >> arr[i][j];
int mark = 2;
unordered_map<int, int> umap;
for (int i = 0; i < n; ++i) {
for (int j = 0; j < m; ++j) {
if (arr[i][j] != 1)
continue;
int cnt = 0;
dfs(i, j, mark, cnt);
umap[mark++] = cnt;
}
}
unordered_set<int> uset;
int max_all = 0;
for (int i = 0; i < n; ++i) {
for (int j = 0; j < m; ++j) {
if (arr[i][j] != 0)
continue;
uset.clear();
int all = 1;
for (int k = 0; k < 4; ++k) {
int x = i + dir[k][0];
int y = j + dir[k][1];
if (x < 0 || x >= n || y < 0 || y >= m)
continue;
if (uset.find(arr[x][y]) != uset.end())
continue;
all += umap[arr[x][y]];
uset.insert(arr[x][y]);
}
max_all = max(max_all, all);
}
}
if (max_all == 0)
cout << umap[arr[0][0]] << endl;
else
cout << max_all << endl;
return0;
}
7、岛屿的周长
题目描述
计算岛屿的周长。只有'1'与'0'的交界处,是可以计入周长的边。
#include<iostream>usingnamespace std;
constint N = 55;
int n, m;
int arr[N][N];
bool used[N][N];
int dir[4][2] = {1, 0, -1, 0, 0, 1, 0, -1};
int cnt = 0;
voiddfs(int x, int y){
if (x < 0 || x >= n || y < 0 || y >= m) {
cnt++;
return;
}
if (used[x][y])
return;
if (arr[x][y] == 0) {
cnt++;
return;
}
used[x][y] = true;
for (int i = 0; i < 4; ++i) {
int cur_x = x + dir[i][0];
int cur_y = y + dir[i][1];
dfs(cur_x, cur_y);
}
}
intmain(){
cin >> n >> m;
for (int i = 0; i < n; ++i)
for (int j = 0; j < m; ++j)
cin >> arr[i][j];
for (int i = 0; i < n; ++i)
for (int j = 0; j < m; ++j) {
if (arr[i][j] == 1) {
dfs(i, j);
cout << cnt << endl;
return0;
}
}
return0;
}
#include<iostream>#include<cstring>#include<list>#include<vector>usingnamespace std;
constint N = 105;
int used[N];
vector<list<int>> graph(N);
int n, m;
voiddfs(int i){
if (used[i] != 0)
return;
used[i] = 1;
for (int node : graph[i])
dfs(node);
}
intmain(){
cin >> n >> m;
for (int i = 0; i < m; ++i) {
int s, t;
cin >> s >> t;
graph[s].push_back(t);
}
dfs(1);
for (int i = 1; i <= n; ++i)
if (used[i] == 0) {
cout << -1 << endl;
return0;
}
cout << 1 << endl;
return0;
}