8.1 DFS
8.1 DFS
http://codeup.hustoj.com/contest.php?cid=100000608
B 【递归入门】组合的输出

题目解析
这题实际是递归求全排列的变体
🆚 求全排列
- 全排列每次从n个数中选择一个没选过的,最后组成n个数的序列;此处从n个数中选择一个没选过的,最后组成r个数的序列
- 全排列中对n个数序列之间的顺序无要求;此处是组合,也就是不要重复的序列,可通过添加限制要求:后一个数一定比前一个数大实现——x>=p[index-1]
代码
#include <cstdio>
#define maxn 25
int n, r, p[maxn];
bool hashtable[maxn] = {false};
void generateP(int index) {
if (index == r + 1) {
for (int i = 1; i <= r; i++) {
printf("%d ", p[i]);
}
printf("\n");
return;
}
for (int x = 1; x <= n; x++) {
if (!hashtable[x] && x >= p[index - 1]) {
p[index] = x;
hashtable[x] = true;
generateP(index + 1);
hashtable[x] = false;
}
}
}
int main() {
while (scanf("%d%d", &n, &r) != EOF) {
generateP(1);
}
return 0;
}
E【递归入门】出栈序列统计

题目解析
题目意思:输入n接下来模拟栈的入栈、出栈操作,需要得到入栈n次,出栈n次。问有几种不同的操作顺序
(一开始愣是没读懂题目啥意思😂)
设入栈次数in_num,出栈次数out_num
所以DFS岔路口是选择入栈还是出栈。
若in_num > n || out_num > n 到达死胡同,in_num == n && out_num == n 表示终点。其他都是岔路口。
但需注意的是,只有 in_num > out_num 时才能出栈
代码
#include <cstdio>
#include <stack>
using namespace std;
stack<int> s;
int n, ans = 0;
//in_num表示入栈次数,out_num表示出栈次数
void DFS(int in_num, int out_num) {
if (in_num == n && out_num == n) {
ans++;
return;
}
if (in_num > n || out_num > n) return;
if (in_num < n) DFS(in_num + 1, out_num); //入栈
if (in_num > out_num && out_num < n) DFS(in_num, out_num + 1); //出栈
}
int main() {
scanf("%d", &n);
DFS(0, 0);
printf("%d\n", ans);
return 0;
}
F 【递归入门】走迷宫

题目解析
⚠️
- 要弄清楚x,y方向和n、m界限分别是对x还是y
- 题目要求按照左上右下方向拓展,这里WA了一次
题外话:这里用bool数组b[i][j]记录点x=i,y=j是否已经走过,但是BFS中用bool数组记录点是否如果队
💡这里代码没有做矩阵有全0行/全0列时肯定无解的剪枝
代码
#include <cstdio>
#include <vector>
using namespace std;
struct node {
int x, y;
};
int n, m,digit=0;
node S,T, Node;
vector<node> ans;
int a[20][20];//存储迷宫的情况
bool b[20][20] = {false};//每个点有没有走过
int X[4] = {0, -1, 0, 1}; //左上右下
int Y[4] = {-1, 0, 1, 0};
bool judge(int x, int y) {
if (x < 1 || x > n || y < 1 || y > m) return false;
if (a[x][y] == 0) return false;
return true;
}
void DFS(int x, int y) {
if (x == T.x && y == T.y) {
for (vector<node>::iterator it = ans.begin();it!=ans.end();it++){
printf("(%d,%d)",(*it).x,(*it).y);
if(it<ans.end()-1) printf("->");
else printf("\n");
}
digit++;
return;
}
for (int i = 0; i < 4; i++) {
int newX = x + X[i];
int newY = y + Y[i];
// 结点可以走,且没被走过
if (judge(newX, newY) && !b[newX][newY]) {
Node.x = newX;
Node.y = newY;
b[newX][newY] = true;
ans.push_back(Node);
DFS(Node.x, Node.y);
ans.pop_back();
b[newX][newY] = false;
}
}
}
int main() {
scanf("%d%d", &n, &m);
for (int i =1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
scanf("%d", &a[i][j]);
}
}
scanf("%d%d", &S.x, &S.y);
scanf("%d%d", &T.x, &T.y);
b[S.x][S.y]= true;
ans.push_back(S);
DFS(S.x,S.y);
if (digit==0) printf("-1");
return 0;
}
本文作者:Joey-Wang
本文链接:https://www.cnblogs.com/joey-wang/p/14541179.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步