递推与递归和DFS深度优先搜索

递推与递归和DFS深度优先搜索

跳台阶

递归实现指数级枚举

递归实现排列型枚举

递归实现组合型枚举

P1036 选数

习题课

递推/ 递归 / DFS

P2089 烤鸡 指数

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <vector>
#include <cstring>
#include <unordered_set>
#include <set>
#include <stack>
#include <map>
#include <cmath>
#include <sstream>
#include <queue>
#define int long long
#define yes cout<<"YES"<<'\n'
#define no 	cout<<"NO"<<'\n'

using namespace std;
const int N = 100008;
int n;
int ans;
vector <vector<int> > res;//储存结果
vector <int> a;//储存每次搜到的答案
void dfs(int x) {
	if (x >= 10) {//搜到第10层的时候开始判断
		int sum = 0;
		for (int i = 0; i < (int)a.size(); i++) {
			sum = sum + a[i];//将这10个数加起来
		}
		if (sum == n) {//如果满足条件
			ans++;//结果加1
			res.push_back(a);//放入结果数列
		}
		return;//返回
	}
	for (int i = 1; i <= 3; i++) {//开始枚举选几克调料
		a.push_back(i);//放入数列
		dfs(x + 1);//递归过去选下一个数
		a.pop_back();//恢复现场
	}


}



signed main () {
	cin >> n;
	dfs(0);//开始dfs
	cout << ans << '\n';//打印所有的次数
	for (int i = 0; i < (int)res.size(); i++) {//打印结果
		for (int j = 0; j < (int)res[i].size(); j++) {
			cout << res[i][j] << ' ';
		}
		cout << '\n';

	}

	return 0;
}


P1088 火星人 全排列

P1149 火柴棒等式 指数 + 预处理

P2036 PERKET 指数

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <vector>
#include <cstring>
#include <unordered_set>
#include <set>
#include <stack>
#include <map>
#include <cmath>
#include <sstream>
#include <queue>
#define int long long
#define yes cout<<"YES"<<'\n'
#define no 	cout<<"NO"<<'\n'

using namespace std;
const int N = 15;
int n;
int arr[N];
int brr[N];
int st[N];//0代表未处理,1代表已经选,2代表不选

int ans = 99999999999999;//结果足够大
void dfs(int x) {
	if (x > n) { //选择了n次之后的结果
		int s = 1, b = 0;//计算当前酸度和苦度
		int flag = 0;//标准变量
		for (int i = 1; i <= n; i++) {
			if (st[i] == 1) {//如果当前选了这个数
				flag = 1;
//				cout<<arr[i]<<' '<<brr[i];
				s = s * arr[i];
				b = b + brr[i];//计算苦度和酸度
			}
		}
		if (flag == 1) {//如果当前会更新酸度和苦度
			ans = min(abs(s - b), ans);//更新ans

		}


//		cout<<'\n';
		return;
	} else {
		st[x] = 2; //不选这个数
		dfs(x + 1); //递归到下一层
		st[x] = 0; //恢复现场
		st[x] = 1; //选这个数
		dfs(x + 1); //递归到下一层
		st[x] = 0; //恢复现场

	}



}
signed main () {
	std::ios::sync_with_stdio(false), std::cin.tie(nullptr), std::cout.tie(nullptr);
	cin >> n;
	for (int i = 1; i <= n; i++) {
		cin >> arr[i] >> brr[i];
	}
	dfs(1);
	cout << ans << '\n';//打印
	return 0;
}

P1135 奇怪的电梯 暴力

迷宫问题

P1683 入门


P1605 迷宫

一道很经典的DFS迷宫问题

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <vector>
#include <cstring>
#include <unordered_set>
#include <set>
#include <stack>
#include <map>
#include <cmath>
#include <sstream>
#include <queue>
#define int long long
#define yes cout<<"YES"<<'\n'
#define no 	cout<<"NO"<<'\n'

using namespace std;
int sx, sy, fx, fy;
const int N = 9;
int n, m;
char mp[N][N];//地图
int dx[6] = {1, -1, 0, 0};
int dy[6] = {0, 0, 1, -1};
bool st[N][N];//状态数组
;
int ans = 0;
void dfs(int x, int y) {
	if (x == fx && y == fy) {//到达终点
		ans++;//路径加1
		return;
	}
	for (int i = 0; i < 4; i++) {
//		cout<<x+dx[i]<<' '<<y+dy[i]<<'\n';

		if ((x + dx[i] >= 1 && x + dx[i] <= n && y + dy[i] >= 1 && y + dy[i] <= m) && mp[x + dx[i]][y + dy[i]] == '.') {//判断有没有出地图范围以及当前地图的点能不能走
			if (st[x + dx[i]][y + dy[i]] == false) {//当前没有被访问过
				st[x + dx[i]][y + dy[i]] = true;//标记为访问
				dfs(x + dx[i], y + dy[i]);//继续深搜
				st[x + dx[i]][y + dy[i]] = false;//恢复现场
			}
		}
	}


}
signed main () {
	memset(mp, '.', sizeof(mp));//'.'代表可以通过
	cin >> n >> m;
	int t;
	cin >> t;
	cin >> sx >> sy >> fx >> fy;
	while (t--) {
		int x, y;
		cin >> x >> y;
		mp[x][y] = '#';//'#'代表是障碍
	}
//	for(int i=1;i<=n;i++){
//		for(int j=1;j<=m;j++){
//			cout<<mp[i][j];
//		}
//		cout<<'\n';
//
//
//	}
	st[sx][sy] = true;//起点标记为已经搜索过
	dfs(sx, sy);//开始搜索
	cout << ans << '\n';//打印结果

	return 0;
}

P1443 马的遍历

P1747 好奇怪的游戏

P2298 Mzc和男家丁的游戏

Flood Fill 洪水灌溉

P1596 Lake Counting S

使用洪水灌溉算法

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <vector>
#include <cstring>
#include <unordered_set>
#include <set>
#include <stack>
#include <map>
#include <cmath>
#include <sstream>
#include <queue>
#define int long long
#define yes cout<<"YES"<<'\n'
#define no 	cout<<"NO"<<'\n'

using namespace std;
const int N = 110;

int n, m;
char mp[N][N];
bool st[N][N];
int dx[] = {1, -1, 0, 0, 1, 1, -1, -1};//向八个方向试探
int dy[] = {0, 0, 1, -1, 1, -1, -1, 1};
int ans = 0;
/*
  进行深度优先搜索
 */
void dfs(int x, int y) {
	for (int i = 0; i < 8; i++) {
		int a = x + dx[i];
		int b = y + dy[i];
		//如果这个点没有访问过,并且在范围之内.并且可以不是障碍
		if (st[a][b] == false && a >= 1 && a <= n && b >= 1 && b <= m && mp[a][b] == 'W') {
			st[a][b] = true;//标记为已经访问
			dfs(a, b);//先下搜索
		}
	}



}
signed main () {
	cin >> n >> m;
	for (int i = 1; i <= n; i++) {
		for (int j = 1; j <= m; j++) {
			cin >> mp[i][j];
		}
	}
	for (int i = 1; i <= n; i++) {
		for (int j = 1; j <= m; j++) {
			if (st[i][j] == false && mp[i][j] == 'W') {//找到一个点开始洪水灌溉
				st[i][j] = true;//标记为已经访问
				dfs(i, j);//开始深搜
				ans++;//答案加1
			}
		}
	}
	cout << ans << '\n';
	return 0;
}

P1451 求细胞数量

也是洪水灌溉算法

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <vector>
#include <cstring>
#include <unordered_set>
#include <set>
#include <stack>
#include <map>
#include <cmath>
#include <sstream>
#include <queue>
#define int long long
#define yes cout<<"YES"<<'\n'
#define no 	cout<<"NO"<<'\n'

using namespace std;
const int N = 110;

int n, m;
char mp[N][N];
bool st[N][N];
int dx[] = {1, -1, 0, 0};
int dy[] = {0, 0, 1, -1};
int ans = 0;
void dfs(int x, int y) {
	for (int i = 0; i < 4; i++) {//4个方向
		int a = x + dx[i];
		int b = y + dy[i];
		//没被访问并且,没有越界,并且字符不为0;
		if (st[a][b] == false && a >= 1 && a <= n && b >= 1 && b <= m && mp[a][b] != '0') {
			st[a][b] = true;//标记为访问
			dfs(a, b);//继续深度搜索

		}
	}



}
signed main () {
	cin >> n >> m;
	for (int i = 1; i <= n; i++) {
		for (int j = 1; j <= m; j++) {
			cin >> mp[i][j];
		}
	}
	for (int i = 1; i <= n; i++) {
		for (int j = 1; j <= m; j++) {
			if (st[i][j] == false && mp[i][j] != '0') {//洪水灌溉
				st[i][j] = true;//标记为访问
				dfs(i, j);
				ans++;//答案加1
			}
		}
	}
	cout << ans << '\n';
	return 0;
}

DFS

acw1114.棋盘问题 排列

P1025 数的划分 组合

P1019 单词接龙 指数 + 预处理

posted @ 2023-04-21 22:34  harper886  阅读(27)  评论(0编辑  收藏  举报