DFS经典例题(八皇后,数独)

1.1P1036 NOIP 2002 普及组 选数


解题思路

这里是组合思想与元素的排序无关,列举出所有符合的组合再判断是否符合素数

代码

cpp 复制代码
#include<iostream>
using namespace std;
const int N = 21;
int a[N];
int path;
int ret;
int n, m;

bool is(int path)
{
	if (path <= 1) return false;

	for (int i = 2; i <= path / i; i++)
	{
		if (path % i == 0)
		{
			return false;
		}
	}
	return true;
}


void dfs(int pos,int begin)
{
	if (pos > m)
	{
		if (is(path))
		{
			ret++;
		}
		return;
	}

	for (int i = begin; i <= n; i++)
	{
		path += a[i];
		dfs(pos + 1, i + 1);
		path -= a[i];
	}

}


int main()
{
	cin >> n >> m;
	for (int i = 1; i <= n; i++)
	{
		cin >> a[i];
	}
	dfs(1,1);
	cout << ret;
	return 0;

}

1.2P9241 蓝桥杯 2023 省 B 飞机降落



解题思路

从数据范围上看只有1-10,我们可考虑用深搜。

eg:有三架飞机,我们可以分成1,2,3 1,3,2 2,3,1 2,1,3 3,1,2 3,2,1六种情况,这是全排列,与元素的顺序有关。

而且根据题目我们可以进行剪枝

代码

cpp 复制代码
#include<iostream>
#include<cstring>
using namespace std;
const int N = 11;
int T[N], D[N], L[N];
bool st[N];
int t, n;
int end,newend;

bool dfs(int pos,int end)
{
	if (pos > n)
	{
		return true;
	}

	for (int i = 1; i <= n; i++)
	{
		if (st[i])
		{
			continue;
		}
		if (end > T[i] + D[i])
		{
			continue;
		}
		st[i] = true;
		newend = max(end, T[i]) + L[i];
		if(dfs(pos + 1,newend)) return true;//有一个条件满足就返回
		st[i] = false;
	}
	return false;
}

int main()
{
	cin >> t;

	while (t--)
	{
		memset(st, 0, sizeof(st));
		cin >> n;
		for (int i = 1; i <= n; i++)
		{
			cin >> T[i] >> D[i] >> L[i];
		}

		if (dfs(1, 0))
		{
			cout << "YES" << endl;
		}
		else
		{
			cout << "NO" << endl;
		}
		
	}
	return 0;
}

1.3P1219 USACO1.5 八皇后 Checker Challenge



解题思路

列举出每种情况,可以使用深搜

但是根据题目中要求进行剪枝

皇后不能放在同一列,同一行,正对角线,副对角线上

代码

cpp 复制代码
#include<iostream>
#include<vector>
using namespace std;
const int N = 14;
vector<int>a;
int n;
int ret;
bool col[N], st1[N*2], st2[N*2];
int p = 15;

void dfs(int x)
{
	if (x > n)
	{
		ret++;
		if (ret <= 3)
		{
			for (auto num : a)
			{
				cout << num << " ";
			}
			cout << endl;
		}
		return;
	}

	for (int i = 1; i <= n; i++)
	{
	  //剪枝
		if (col[i] || st1[i-x + p] || st2[i+x])
		{
			continue;
		}
		a.push_back(i);
		col[i] = st1[i-x + p] = st2[i+x] = true;
		dfs(x + 1);
		a.pop_back();
		col[i] = st1[i-x + p] = st2[i+x] = false;
	}

}


int main()
{
	cin >> n;
	dfs(1);
	cout << ret;
	return 0;
}

1.4P1784 数独




解题思路

暴搜,一个一个格子去填

从1-9开始开始,合适的填进去,再填下一个格子

剪枝

代码

cpp 复制代码
#include<iostream>
using namespace std;
const int N = 11;
int a[N][N];
bool col[N][N], row[N][N], st[N][N][N];
int n = 8;

bool dfs(int x,int y)
{
	if (x > n)
	{
		return true;
	}

	if (y > n)
	{
		return dfs(x + 1, 0);
	}

	if (a[x][y]) 
	{
		return dfs(x, y + 1);
	}


	for (int i = 1; i <= 9; i++)
	{
		if (row[x][i] || col[y][i] || st[x / 3][y / 3][i])
		{
			continue;
		}
		a[x][y] = i;
		row[x][i] = col[y][i] = st[x / 3][y / 3][i] = true;
		if(dfs(x, y + 1)) return true;
		row[x][i] = col[y][i] = st[x / 3][y / 3][i] = false;
		a[x][y] = 0;
	}
	return false;
}

int main()
{
	for (int i = 0; i <= n; i++)
	{
		for (int j = 0; j <= n; j++)
		{
			cin >> a[i][j];
			if (a[i][j])
			{
				row[i][a[i][j]] = col[j][a[i][j]] = st[i/3][j/3][a[i][j]] = true;
			}
		}
	}

	if (dfs(0,0))
	{
		for (int i = 0; i <= n; i++)
		{
			for (int j = 0; j <= n; j++)
			{
				cout << a[i][j] <<" ";
			}
			cout << endl;
		}
	}
	return 0;
}
相关推荐
Sw1zzle2 小时前
算法入门(四):二叉树 - 递归遍历三件套
算法·leetcode
万法若空2 小时前
【算法-查找】查找算法
java·数据结构·算法
海石2 小时前
子树怎么找?树的3种遍历方式来帮忙!
算法·leetcode
海石2 小时前
难度分 1588:思路 + 技巧 = AC
算法·leetcode
珠海西格电力6 小时前
云边端协同架构:零碳园区管理系统的技术底座
大数据·运维·人工智能·算法·架构·能源
还有多久拿退休金8 小时前
让飞书知识库跟着 commit 自己长:一套自动化知识库的真实实现
前端·算法·架构
KaMeidebaby9 小时前
卡梅德生物技术快报|小 RNA 适配体合成 + 多方法亲和力表征全流程标准化操作手册
前端·网络·数据库·人工智能·算法
是Dream呀9 小时前
基于深度学习的人类行为识别算法研究
人工智能·深度学习·算法
happyprince10 小时前
03_NVIDIA_ModelOpt-量化算法深入
人工智能·深度学习·算法
大鱼>10 小时前
AI+货物追踪:智能快递柜追踪系统
人工智能·深度学习·算法·机器学习