用c++实现:在一个nm二维网格图中,有以下三种地形:'#'代表湖泊;'.'代表陆地;'?'代表陆地与湖泊均有可能的未知地形。 求是否存在一种或多种在未知地形填充湖泊/陆地的方案,使得最后地上全部的陆地区域组成一个四联通的联通块(陆地四联通是指,在任意一个陆地格子出发,只是任意使用上下左右四个方向操作,可以访问到任何一块其他的陆地)。 无解输出“Impossible”,多解输出“Ambiguous”,唯一解则须输出一个nm的网格图,使得之前的“?”均被填充为“#”或“.”,且陆地四联通。
时间: 2024-02-25 14:59:31 浏览: 50
数据结构教程--用C++实现的方法
以下是用C++实现的代码,与上一个问题的代码类似,只是输入和输出方式有所不同:
```c++
#include <iostream>
#include <vector>
#include <cstring>
using namespace std;
const int MAXN = 50 + 5; // 最大网格图大小
const int dx[] = {0, 0, 1, -1}; // 四联通的四个方向
const int dy[] = {1, -1, 0, 0};
int n, m, cnt; // 网格图大小和连通块数量
char grid[MAXN][MAXN]; // 网格图
bool vis[MAXN][MAXN]; // 是否访问过
vector<pair<int, int>> unknown; // 未知地形的位置
vector<pair<int, int>> land; // 陆地的位置
// 判断一个位置是否在网格图中
bool inGrid(int x, int y) {
return x >= 0 && x < n && y >= 0 && y < m;
}
// DFS遍历连通块,返回连通块大小
int dfs(int x, int y) {
vis[x][y] = true;
int res = 1;
for (int i = 0; i < 4; i++) {
int nx = x + dx[i], ny = y + dy[i];
if (inGrid(nx, ny) && !vis[nx][ny] && grid[nx][ny] == '.') {
res += dfs(nx, ny);
}
}
return res;
}
// 判断是否存在一种或多种填充方案使得最后地上全部的陆地区域组成一个四联通的联通块
bool check() {
memset(vis, false, sizeof(vis));
int cntLand = 0, cntConn = 0;
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
if (grid[i][j] == '.' && !vis[i][j]) {
cntConn++;
int size = dfs(i, j);
cntLand += size;
if (cntConn > 1 || cntLand != land.size()) {
return false;
}
}
}
}
return cntConn == 1;
}
// DFS搜索所有填充方案,返回方案数量
int dfsFill(int idx) {
if (idx == unknown.size()) {
if (check()) {
cnt++;
return 1;
} else {
return 0;
}
}
int x = unknown[idx].first, y = unknown[idx].second;
int res = 0;
grid[x][y] = '#';
res += dfsFill(idx + 1);
if (res > 1) {
return res;
}
grid[x][y] = '.';
res += dfsFill(idx + 1);
if (res > 1) {
return res;
}
return res;
}
int main() {
cin >> n >> m;
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
cin >> grid[i][j];
if (grid[i][j] == '?') {
unknown.push_back(make_pair(i, j));
} else if (grid[i][j] == '.') {
land.push_back(make_pair(i, j));
}
}
}
int res = dfsFill(0);
if (res == 0) {
cout << "Impossible" << endl;
} else if (res == 1) {
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
cout << grid[i][j];
}
cout << endl;
}
} else {
cout << "Ambiguous" << endl;
}
return 0;
}
```
输入格式为:
```
n m
grid[0][0] grid[0][1] ... grid[0][m-1]
grid[1][0] grid[1][1] ... grid[1][m-1]
...
grid[n-1][0] grid[n-1][1] ... grid[n-1][m-1]
```
其中,$n$和$m$分别表示网格图的行数和列数,$grid[i][j]$表示第$i$行$j$列的网格图。例如:
```
4 4
.#..
.?#.
..?.
....
```
输出结果为:
- 如果无解,输出`Impossible`;
- 如果有唯一解,输出一个$n\times m$的网格图,使得之前的“?”均被填充为“#”或“.”,且陆地四联通;
- 如果有多解,输出`Ambiguous`。
阅读全文