每日一题 - 240321 - 路径之谜

这篇文章介绍了如何使用深度优先搜索(DFS)算法解决一个二维空间中寻找特定路径的问题,涉及状态转移、计数器管理和恢复现场的技巧,时间复杂度讨论也在文中出现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


  • 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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值