DFS练习

问题 A: 【递归入门】全排列
水题…

#include <iostream>
using namespace std;
int n;
int a[15], vis[15];
void dfs(int step)
{
	if (step == n + 1)
	{
		for (int i = 1; i <= n; i++)
		{
			if (i == 1)
			{
				cout << a[i];
			}
			else
			{
				cout << " " << a[i];
			}
		}
		cout << endl;
		return;
	}
	for (int i = 1; i <= n; i++)
	{
		if (!vis[i])
		{
			a[step] = i;
			vis[i] = 1;
			dfs(step + 1);
			vis[i] = 0;
		}
	}
}
int main()
{
	cin >> n;
	dfs(1);
	return 0; 
 } 

问题 B: 【递归入门】组合的输出
这个题和上面差不多,只是循环开始是从上次所选的数字开始

#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std; 
int n, r ;; 
int a[105], vis[105]; 
void dfs(int step)
{
	if(step == r + 1)
	{
		for(int i = 1; i <= r; i++)
		{
			if (i == 1)
			{
				cout << a[i];
			}
			else
			{
				cout << " " << a[i];
			}
		}
		cout << endl;
		return;
	}
	for(int i = a[step - 1] + 1; i <= n; i++)
	{
		if (!vis[i])
		{
			vis[i] = 1;
			a[step] = i;
			dfs(step + 1);
			vis[i] = 0;
		}
	}
}
int main()
{
	cin >> n >> r;
	dfs(1);
	return 0;
}

问题 C: 【递归入门】组合+判断素数
这题做过好几次了,一遍过

#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std; 
int n, k, ans; 
int a[25]; 
bool is_true(int x)
{
	for (int i = 2; i * i <= x; i++)
	{
		if (x % i == 0)
		{
			return false;
		}
	}
	return true;
}
void dfs(int step, int x, int sum)
{
	if (x == k && is_true(sum))
	{
		ans++;
		return;
	}
	if (step == n)
	{
		return;
	}
	dfs(step + 1, x + 1, sum + a[step]);
	dfs(step + 1, x, sum);
}
int main()
{
	cin >> n >> k;
	for (int i = 0; i < n; i++)
	{
		cin >> a[i];
	}
	dfs(0, 0, 0);
	cout << ans << endl;
	return 0;
}

问题 D: 【递归入门】n皇后 问题(原始的8皇后问题)

#include <iostream>
using namespace std;
int n, ans;
int x1[15], x2[15], c[40], t[40], flag;
int check(int r, int i)
{
    return !c[i] && !x1[r + i] && !x2[r - i + n];
}
void dfs(int r)
{
	if (r == n)
	{
		flag = 1;
		for (int i = 0; i < n; i++)
		{
			if (i == 0)
			{
				cout << t[i];
			}
			else
			{
				cout << " " << t[i];
			}
		}
		cout << endl;
		return;
	}
	for (int i = 1; i <= n; i++)
	{
		if (check(r, i))
		{
			c[i] = x1[r + i] = x2[r - i + n] = 1;
			t[r] = i;
			dfs(r + 1);
			c[i] = x1[r + i] = x2[r - i + n] = 0;
			t[r] = 0;
		}
	}
}
int main()
{
	cin >> n;
	dfs(0);
	if (flag == 0)
	{
		cout << "no solute!" << endl;
	}
	return 0;
}

问题 E: 【递归入门】出栈序列统计
分析:用一个过程来模拟进出栈的过程,递归两个参数,一个是栈内元素个数,另一个是还剩几个数等待入栈。当等待入栈元素个数为0时,说明元素已经全部出栈,方案数加一并return;如果栈内元素个数为0,那就入栈,否则既可以入栈也可以出栈。

#include <iostream>
using namespace std;
int ans;
void dfs(int in, int out)
{
	if (out == 0)
	{
		ans++;
	}
	else if (in == 0)
	{
		dfs(in + 1, out- 1);
	}
	else
	{
		dfs(in + 1, out - 1);
		dfs(in - 1, out);
	}
}
int main()
{
	int n;
	while (cin >> n)
	{
		ans = 0;
		dfs(0, n);
		cout << ans << endl; 
	}
	return 0;
}

问题 F: 【递归入门】走迷宫
分析:用一个a数组来存放迷宫可走的情况,另外用一个结构体数组route来存放哪些点走过了。每个点用两个数字来描述,一个表示行号,另一个表示列号。后面都是套路,照着套路敲就行了。

#include <iostream>
using namespace std;
int a[20][20], sx, sy, ex, ey, n, m, flag, num;
int dir[4][2] = {{0, -1}, {-1, 0}, {0, 1}, {1, 0}};
struct Route {
	int x, y;
}route[5000];
bool in(int x, int y)
{
	return 1 <= x && x <= n && 1 <= y && y <= m;
}
void dfs(int x, int y)
{
	if (x == ex && y == ey)
	{
		flag = 1;
		for (int i = 0; i < num; i++) 
		{
			cout << "(" << route[i].x << "," << route[i].y << ")->";
		}
		cout << "(" << ex << "," << ey << ")" << endl;
		return;
	}
	route[num].x = x, route[num].y = y;
	for (int i = 0; i < 4; i++)
	{
		int tx = x + dir[i][0], ty = y + dir[i][1];
		if (a[tx][ty] && in(tx, ty))
		{
			a[x][y] = 0;
			num++; 
			dfs(tx, ty);
			num--;
			a[x][y] = 1;
		}
	}
}
int main()
{
	cin >> n >> m;
	for (int i = 1; i <= n; i++)
	{
		for (int j = 1; j <= m; j++)
		{
			cin >> a[i][j];
		}
	}
	cin >> sx >> sy >> ex >> ey;
	dfs(sx, sy);
	if (!flag)
	{
		cout << "-1" << endl;
	}
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值