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;
}
相关推荐
艾为电子14 分钟前
【应用方案】电视沉浸式音频升级: 电视音频 awinic“芯片 + 算法” 一体化解决方案
算法·音视频
大熊背28 分钟前
树莓派相机自动白平衡详解(二)
算法·白平衡·isppipeline
Scabbards_1 小时前
面试Leetcode - 算法合集
算法·leetcode·面试
chuan.bai1 小时前
Java RAG 实战附录:qwen3 与 bge-m3 模型切换指南
java·人工智能·算法
wuyk5551 小时前
7.AVL 树:第一个自平衡二叉搜索树
开发语言·stm32·单片机·算法
rannn_1111 小时前
【力扣hot100】二叉树专题+总结
java·算法·leetcode·二叉树
啊嘞嘞?1 小时前
力扣(岛屿数量)
算法·leetcode
zander2581 小时前
LeetCode 198. 打家劫舍
算法·leetcode·深度优先
吃着火锅x唱着歌1 小时前
LeetCode 648.单词替换
算法·leetcode·职场和发展
一只积极向上的小咸鱼2 小时前
分词器tokenizer
算法·llm