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;
}
相关推荐
进击的小头1 小时前
第18篇:PID参数整定与裕度优化的现场调试实战
python·算法
cpp_25011 小时前
P1796 汤姆斯的天堂梦
数据结构·c++·算法·题解·洛谷·线性dp
凌波粒2 小时前
LeetCode--19.删除链表的倒数第 N 个结点(链表)
java·算法·leetcode·链表
Fcy6482 小时前
与红黑树有关算法题
算法
爱搞虚幻的阿恺2 小时前
UE入门-如何使用结构体数组创建动态UI
算法
重生之我是Java开发战士2 小时前
【广度优先搜索】多源BFS:矩阵,飞地的数量,地图中的最高点,地图分析
数据结构·算法·矩阵·广度优先
sali-tec3 小时前
C# 基于OpenCv的视觉工作流-章43-轮廓匹配
图像处理·人工智能·opencv·算法·计算机视觉
Coovally AI模型快速验证3 小时前
检测+跟踪一体化!4.39M参数、8.3W功耗,轻量化模型让无人机在露天矿实时巡检
算法·yolo·无人机·智能巡检·智慧矿山
玛卡巴卡ldf3 小时前
【LeetCode 手撕算法】(矩阵)73-矩阵置零、54-螺旋矩阵(贪吃蛇)、48-旋转图像
java·数据结构·算法·leetcode·力扣