dfs
一开始写成广搜了,调半天没整出来,后来感觉深搜更好。。。
本题是要求能把所有士兵全部包围起来的最少陷阱数。
- 不用考虑有单独存在的士兵,题目保证士兵是连通的。
- 同时边界不存在士兵。
一开始想写广搜,把每一个士兵存到队列里,依次拿出队首元素,遍历四个方向,如果有. 就放陷阱*,如果是士兵#就放入队列中。
但是这样是有问题的。以样例1为例,这样会把被士兵围着的.也换成陷阱*,但正解是不用放的。所以如果写bfs就要特判.四周是不是都是士兵#这种情况,有点麻烦。
dfs就能避免这种问题
为什么?
dfs从起点(1,1)开始遍历,dfs深搜搜的是空地.的四个方向,如果空地四个方向有士兵#,就把空地.换成陷阱#。如果是空地.,就dfs这个空地。
dfs是不会去搜被士兵包围的空地的,因为是从起点空地开始搜,如果被士兵包围,搜到士兵就结束了,是搜不到被士兵里面的空地的。
小细节
- 判断越界
- st[N]数组剪枝
- 方向偏移量
#include<bits/stdc++.h>
#define ios ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
#define bug(x) cout<<#x<<"=="<<x<<endl;
#define endl "\n"
#define fi first
#define se second
using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
const int INF = 0x3f3f3f3f;
const int inf = 0xc0c0c0c0;
const int N = 600;
char a[N][N];
int n, m;
int dx[] = {-1, 1, 0, 0};
int dy[] = {0, 0, -1, 1};
bool st[N][N];
void dfs(int x, int y) {
st[x][y] = 1;
for (int i = 0; i < 4; i++) {
int xx = x + dx[i], yy = y + dy[i];
if (st[xx][yy]) continue;
if (xx < 1 || xx > n || yy < 1 || yy > m) continue;
if (a[xx][yy] == '#') a[x][y] = '*';
if (a[xx][yy] == '.') dfs(xx, yy);
}
}
int main() {
ios;
cin >> n >> m;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
cin >> a[i][j];
}
}
dfs(1, 1);
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
cout << a[i][j];
}
cout << endl;
}
return 0;
}

浙公网安备 33010602011771号