c++实现:在一个n*m二维网格图中,有以下三种地形:'#'代表湖泊;'.'代表陆地;'?'代表陆地与湖泊均有可能的未知地形。 求是否存在一种或多种在未知地形填充湖泊/陆地的方案,使得最后地上全部的陆地区域组成一个四联通的联通块(陆地四联通是指,在任意一个陆地格子出发,只是任意使用上下左右四个方向操作,可以访问到任何一块其他的陆地)。 无解输出“Impossible”,多解输出“Ambiguous”,唯一解则须输出一个n*m的网格图,使得之前的“?”均被填充为“#”或“.”,且陆地四联通。
时间: 2024-02-12 17:07:43 浏览: 60
详解C++中的一维数组和二维数组
5星 · 资源好评率100%
以下是C++的代码实现:
```cpp
#include <iostream>
#include <vector>
#include <queue>
using namespace std;
const int MAXN = 1005;
const int dx[4] = {0, 0, 1, -1};
const int dy[4] = {1, -1, 0, 0};
int n, m;
char grid[MAXN][MAXN];
bool vis[MAXN][MAXN];
bool check() {
queue<pair<int, int>> q;
bool flag = false;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
if (grid[i][j] == '.') {
q.push(make_pair(i, j));
flag = true;
break;
}
}
if (flag) break;
}
memset(vis, false, sizeof(vis));
vis[q.front().first][q.front().second] = true;
while (!q.empty()) {
pair<int, int> cur = q.front();
q.pop();
for (int i = 0; i < 4; i++) {
int nx = cur.first + dx[i];
int ny = cur.second + dy[i];
if (nx < 1 || nx > n || ny < 1 || ny > m) continue;
if (vis[nx][ny] || grid[nx][ny] == '#') continue;
vis[nx][ny] = true;
q.push(make_pair(nx, ny));
}
}
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
if (grid[i][j] == '.' && !vis[i][j]) return false;
}
}
return true;
}
bool dfs(int x, int y, bool is_land) {
if (x == n+1) return check();
int nx, ny;
if (y == m) {
nx = x + 1;
ny = 1;
} else {
nx = x;
ny = y + 1;
}
if (grid[x][y] != '?') return dfs(nx, ny, is_land);
if (is_land) {
grid[x][y] = '#';
if (dfs(nx, ny, false)) return true;
grid[x][y] = '.';
return dfs(nx, ny, true);
} else {
grid[x][y] = '.';
if (dfs(nx, ny, true)) return true;
grid[x][y] = '#';
return dfs(nx, ny, false);
}
}
int main() {
cin >> n >> m;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
cin >> grid[i][j];
}
}
if (!dfs(1, 1, true)) {
cout << "Impossible" << endl;
} else {
int cnt = 0;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
if (grid[i][j] == '?') cnt++;
}
}
if (cnt > 0) {
cout << "Ambiguous" << endl;
} else {
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
cout << grid[i][j];
}
cout << endl;
}
}
}
return 0;
}
```
首先,我们采用DFS的方式枚举每个未知地形的填充方案,然后检查每个方案是否满足四联通的连通性。对于每个未知地形,我们可以选择填充湖泊或者陆地,所以最坏情况下复杂度会达到 $O(2^{n \times m})$。但是实际上,由于我们在检查每个方案的时候会进行剪枝,因此实际运行时间应该会远远低于最坏情况下的时间复杂度。
在具体实现中,我们首先需要写一个check函数,用于检查当前填充方案是否满足四联通的连通性。具体来说,我们从网格图中任意找一个陆地格子出发,使用BFS或DFS进行遍历,标记所有与该陆地格子四联通相连的陆地格子。最后,我们判断是否有未被标记的陆地格子存在,如果存在,则说明当前填充方案无法满足四联通的连通性,返回false,否则返回true。
接下来,我们使用DFS进行枚举。对于每个未知地形,我们依次尝试填充湖泊和陆地。具体来说,我们在dfs函数中判断当前位置是否为未知地形,如果不是,则直接跳到下一个位置;如果是,则分别尝试填充湖泊和陆地,对于每个填充方案,我们递归调用dfs函数进行下一步枚举。如果有一种填充方案满足四联通的连通性,则直接返回true,否则继续尝试下一种填充方案。如果所有填充方案都不满足四联通的连通性,则返回false。
最后,我们需要判断是否存在多解,即是否存在未知地形没有被填充的情况。如果存在多解,则输出"Ambiguous";否则输出唯一的填充方案。
阅读全文