深度优先搜索

本文探讨了全排列问题的解决方法,通过深度优先搜索(DFS)实现,展示了如何在遇到“#”字符时进行连通图的遍历,并应用于拯救oibh总部和迷宫问题的求解。示例代码详细解释了DFS在不同场景下的应用,包括从外部四周搜索和由特定起点开始的搜索策略。

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

全排列问题:

#include <iostream>
using namespace std;
int n;
int flag[10001], a[10001];
void dfs(int index)
{
	if (index == n + 1)
	{
		for (int i = 1; i <= n; i++)
			cout << a[i] << " ";
		cout << endl;
		return;
	}
	for (int i = 1; i <= n; i++)
	{
		if (flag[i] == 0)
		{
			a[index] = i;
			flag[i] = 1;
			dfs(index + 1);
			flag[i] = 0;
		}
	}
}
int main()
{
	cin >> n;
	dfs(1);
	return 0;
}

//回溯 剪枝

DFS连通图

洛谷P1454 圣诞夜的极光 https://www.luogu.com.cn/problem/P1454

#include <iostream>
using namespace std;
char arr[1005][1005];
int s = 0;
int n, m;
int x[13] = { 0,1,-1,0,0,2,-2,0,0,1,-1,1,-1 };
int y[13] = { 0,0,0,1,-1,0,0,2,-2,-1,1,1,-1 };
void dfs(int xx, int yy)
{
	if (xx > n || yy > m || arr[xx][yy] != '#')
		return;
	arr[xx][yy] = '-';
	for (int i = 1; i <= 12; i++)
		dfs(xx + x[i], yy + y[i]);
}
int main()
{
	cin >> n >> m;
	for (int i = 1; i <= n; i++)
		for (int j = 1; j <= m; j++)
			cin >> arr[i][j];
	for (int i = 1; i <= n; i++)
		for (int j = 1; j <= m; j++)
		{
			if (arr[i][j] == '#')
				s++;
			dfs(i, j);
		}
	cout << s;
	return 0;
}

通过遍历,如果找到“#”就结果自加,同时将该点上的符号删除(改为“-”),然后向上下左右(或者包括左上左下右上右下)搜索,如此操作。

洛谷P1506 拯救oibh总部

#include <iostream>
using namespace std;
int n, m;
char a[505][505];
bool flag[505][505];
int xx[5] = { 0,1,-1,0,0 };
int yy[5] = { 0,0,0,1,-1 };
void dfs(int x, int y)
{
	a[x][y] = '1';
	for (int i = 1; i <= 4; i++)
	{
		if (x + xx[i] > 0 && x + xx[i] <= n && y + yy[i] > 0 && y + yy[i] <= m && a[x + xx[i]][y + yy[i]] == '0')
			dfs(x + xx[i], y + yy[i]);
	}
}
int main()
{
	memset(flag, true, sizeof(flag));//提交记得头文件
	cin >> n >> m;
	for (int i = 1; i <= n; i++)
		for (int j = 1; j <= m; j++)
			a[i][j] = '1';
	for (int i = 1; i <= n; i++)
		for (int j = 1; j <= m; j++)
			cin >> a[i][j];
	for (int i = 1; i <= m; i++)
		if (a[1][i] == '0') dfs(1, i);
	for (int i = 1; i <= m; i++)
		if (a[n][i] == '0') dfs(n, i);
	for (int i = 1; i <= n; i++)
		if (a[i][1] == '0')dfs(i, 1);
	for (int i = 1; i <= n; i++)
		if (a[i][m] == '0')dfs(i, m);
	int ans = 0;
	for (int i = 1; i <= n; i++)
		for (int j = 1; j <= m; j++)
			if (a[i][j] == '0')
				ans++;
	cout << ans;
	return 0;
}

由外部四周进行搜索,如果没碰到“壁垒”,就将其“淹没”。 

迷宫问题

洛谷P1605 迷宫https://www.luogu.com.cn/problem/P1605

#include <iostream>
using namespace std;
int n, m, t;
int a[150][105] = { 0 };
int xx[5] = { 0,1,-1,0,0 };
int yy[5] = { 0,0,0,1,-1 };
int sx, sy, fx, fy;
int zx, zy;
int ans = 0;
void dfs(int x, int y)
{
    if (x == fx && y == fy)
    {
        ans++;
        return;
    }
    else
    {
        a[x][y] = 0;
        for (int i = 1; i <= 4; i++)
        {
            if (x <= n && y <= m && a[x + xx[i]][y + yy[i]] == 1)
            {
                dfs(x + xx[i], y + yy[i]);
                a[x+xx[i]][y+yy[i]] = 1;
            }

        }
    }
}
int main()
{
    //memset(a, 0, sizeof(a));
    cin >> n >> m >> t;
    cin >> sx >> sy >> fx >> fy;
    for (int i = 1; i <= n; i++)
        for (int j = 1; j <= m; j++)
            a[i][j] = 1;
    for (int i = 1; i <= t; i++)
    {
        cin >> zx >> zy;
        a[zx][zy] = 0;
    }
    dfs(sx, sy);
    cout << ans;
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值