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;
}
相关推荐
圣光SG6 小时前
Java操作题练习(七)
java·开发语言·算法
Cx330_FCQ8 小时前
Tmux使用
服务器·git·算法
拳里剑气9 小时前
C++算法:多源BFS
c++·算法·宽度优先·多源bfs
ysa05103010 小时前
【板子】短序列dp(换成维护更小常数维度的dp)
c++·笔记·算法·板子
shwill12310 小时前
PID 算法(三)--- 增量 PID ↔ 单神经元 PID 等价映射
linux·算法
wabs66611 小时前
关于图论【卡码网110.字符串迁移的思考】
数据结构·算法·图论
hanlin0311 小时前
刷题笔记:力扣第242、349题(哈希表)
笔记·算法·leetcode
浮沉98712 小时前
二分查找算法例题(二)
算法
only-qi13 小时前
大模型Agent面试攻略:落地工程痛点、评估体系与Agentic RAG核心精讲
人工智能·算法·面试·职场和发展·langchain·rag
Gauss松鼠会15 小时前
【GaussDB】GaussDB锁阻塞源头查询
java·开发语言·前端·数据库·算法·gaussdb·经验总结