先贴个题目:
以及原题链接:1233. 全球变暖 - AcWing题库https://www.acwing.com/problem/content/1235/
flood fill 算法,和AcWing 1113. 红与黑 解题思路及代码-CSDN博客差不多,但我之前刚开始的思路是先搜索一遍岛屿数量,然后把海平面上升后的地图表示出来然后再搜一遍,二者相减就是最终答案,代码如下:
#include <iostream>
#include <cstring>
#include <queue>
using namespace std;
typedef pair<int, int> PII;
#define x first
#define y second
const int N = 1010;
int n;
char map[N][N];
bool sign[N][N];
int dx[4] = {0, 0, -1, 1}, dy[4] = {1, -1, 0, 0};
void bfs(int x, int y)
{
PII start = make_pair(x, y);
sign[x][y] = true;
queue<PII> q;
q.push(start);
while(q.size())
{
PII tmp = q.front();
q.pop();
for (int i = 0; i < 4;++i)
{
int tx = tmp.x + dx[i];
int ty = tmp.y + dy[i];
if(tx<0||tx>=n||ty<0||ty>=n)
continue;
if(!sign[tx][ty]&&map[tx][ty]=='#')
{
sign[tx][ty] = true;
q.push(make_pair(tx, ty));
}
}
}
}
int main()
{
cin >> n;
for (int i = 0; i < n; ++i)
scanf("%s", map[i]);
int before = 0, now = 0;
for (int i = 0; i < n; ++i) // 搜索原先的岛屿数
for (int j = 0; j < n; ++j)
{
if (map[i][j] == '#' && !sign[i][j])
{
before++;
bfs(i, j);
}
}
for (int i = 0; i < n; ++i) // 模拟海平面上升后的岛屿情况
for (int j = 0; j < n; ++j)
{
if (map[i][j] == '#')
{
for (int k = 0; k < 4; ++k)
{
int tx = i + dx[k];
int ty = j + dy[k];
if (tx < 0 || tx >= n || ty < 0 || ty >= n)
continue;
if (map[tx][ty] == '.')
{
map[i][j] = '*';
break;
}
}
}
}
memset(sign, 0, sizeof(sign)); // 重置标记
for (int i = 0; i < n; ++i) // 搜索海平面上升后的岛屿数
for (int j = 0; j < n; ++j)
{
if (map[i][j] == '#' && !sign[i][j])
{
now++;
bfs(i, j);
}
}
cout << before - now;
return 0;
}
然后发现如果出现:
9
.........
.##.##...
.#####...
.##.##...
.........
.##.#....
.#.###...
.#..#....
.........
这种情况,就会出现错误,错误原因是原来上面那个大岛在被淹没后会变成两个小岛,导致计数出问题,所以不行,于是我就换了个思路,搜索四周没有海域的地块,如果一整块大陆都没有,就让被淹没的岛屿数加一,然后ac了,写了两个版本,bfs和dfs的。
先贴个bfs的:
#include <iostream>
#include <cstring>
#include <queue>
using namespace std;
typedef pair<int, int> PII;
#define x first
#define y second
const int N = 1010;
int n;
char map[N][N];
bool sign[N][N];
int dx[4] = {0, 0, -1, 1}, dy[4] = {1, -1, 0, 0};
bool bfs(int x, int y)
{
bool sign1 = true;
PII start = make_pair(x, y);
sign[x][y] = true;
queue<PII> q;
q.push(start);
while (q.size())
{
int cnt = 0;
PII tmp = q.front();
q.pop();
for (int i = 0; i < 4; ++i)
{
int tx = tmp.x + dx[i];
int ty = tmp.y + dy[i];
if (tx < 0 || tx >= n || ty < 0 || ty >= n)
continue;
if (!sign[tx][ty] && map[tx][ty] == '#')
{
sign[tx][ty] = true;
q.push(make_pair(tx, ty));
}
if (map[tx][ty] == '.')
cnt++;
}
if (!cnt)
sign1 = false;
}
return sign1;
}
int main()
{
cin >> n;
for (int i = 0; i < n; ++i)
scanf("%s", map[i]);
int ans = 0;
for (int i = 0; i < n; ++i)
for (int j = 0; j < n; ++j)
{
if (map[i][j] == '#' && !sign[i][j])
{
if (bfs(i, j))
ans++;
}
}
cout << ans;
return 0;
}
再贴个dfs的:
#include <iostream>
using namespace std;
const int N = 1010;
int n;
char map[N][N];
bool sign[N][N];
int dx[4] = {0, 0, -1, 1}, dy[4] = {-1, 1, 0, 0};
bool dfs(int x, int y)
{
bool sign1 = false, sign2 = false;
int cnt = 0;
for (int i = 0; i < 4; ++i)
{
int tx = x + dx[i];
int ty = y + dy[i];
if (tx < 0 || tx >= n || ty < 0 || ty >= n)
continue;
if (map[tx][ty] == '#' && !sign[tx][ty])
{
sign[tx][ty] = true;
sign2 = dfs(tx, ty);
sign1 = sign1 || sign2;
}
if (map[tx][ty] == '.')
cnt++;
}
if (!cnt)
sign1 = true;
return sign1;
}
int main()
{
cin >> n;
for (int i = 0; i < n; ++i)
scanf("%s", map[i]);
int ans = 0;
for (int i = 0; i < n; ++i)
for (int j = 0; j < n; ++j)
{
if (map[i][j] == '#' && !sign[i][j])
{
sign[i][j] = true;
if (!dfs(i, j))
ans++;
}
}
cout << ans;
return 0;
}
by————2024.4.7刷题记录