TAG
- 芝士水题、算法 − 【搜索 − D F S 】 芝士水题、算法 - 【搜索 - DFS】 芝士水题、算法−【搜索−DFS】时间复杂度
- O ( ∗ ) O(\ast) O(∗)
//
#include <bits/stdc++.h>
using namespace std;
// #define int long long
const int dx[] = {0, 0, 1, -1};
const int dy[] = {1, -1, 0, 0};
const int N = 30;
bool used[N][N];
int cnt_J[N], cnt_I[N], ans[N * N];
int n;
void dfs(int x, int y, int idx) {
ans[idx] = x * n + y;
// 显然,需要恢复现场的搜索,不适合在函数的首尾增删标记
// 因为在特判答案时的直接 `return` 会让尾部的删标记无法执行
//
// for (int i = 0; i <= idx; i++) {
// printf("%d%c", ans[i], " \n"[i == idx]);
// }
// if (ans[idx] == 14) {
// cout << "@" << endl;
// cout << x << " " << y << endl;
// for (int i = 0; i < n; i++) {
// for (int j = 0; j < n; j++) {
// cout << used[i][j] << " \n"[j == n - 1];
// }
// }
// for (int i = 0; i < n; i++) {
// cout << cnt_I[i] << " " << cnt_J[i] << endl;
// }
// cout << "@" << endl;
// }
//
if (x == n - 1 && y == n - 1) {
for (int i = 0; i < n; i++) {
if (cnt_I[i] || cnt_J[i]) return ;
}
for (int i = 0; i <= idx; i++) {
printf("%d%c", ans[i], " \n"[i == idx]);
}
return ;
}
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 (used[tx][ty] || cnt_I[tx] == 0 || cnt_J[ty] == 0) continue;
used[tx][ty] = 1; cnt_I[tx]--; cnt_J[ty]--;
dfs(tx, ty, idx + 1);
used[tx][ty] = 0; cnt_I[tx]++; cnt_J[ty]++;
}
}
void solve() {
scanf("%d", &n);
for (int i = 0; i < n; i++) scanf("%d", &cnt_J[i]);
for (int i = 0; i < n; i++) scanf("%d", &cnt_I[i]);
used[0][0] = 1; cnt_I[0]--; cnt_J[0]--;
dfs(0, 0, 0);
}
signed main() {
int t = 1;
// scanf("%d", &t);
while (t--) solve();
return 0;
}
实现细节
恢复现场
参考示意图
-
`
参考链接
- `
作者 | 乐意奥AI