洛谷P1157组合的输出 递归:我他又来辣

没没没没没没没错,这是一道简单的递归(其实是深搜加回溯)

我不管,我说是递归就是递归。

上题干:

题目描述

排列与组合是常用的数学方法,其中组合就是从 n 个元素中抽出 r个元素(不分顺序且 r≤n),我们可以简单地将 n 个元素理解为自然数 1,2,...,n,从中任取 r 个数。

现要求你输出所有组合。

例如 n=5,r=3,所有组合为:

123,124,125,134,135,145,234,235,245,345123,124,125,134,135,145,234,235,245,345。

输入格式

一行两个自然数n,r(1<n<21,0≤r≤n)。

输出格式

所有的组合,每一个组合占一行且其中的元素按由小到大的顺序排列,每个元素占三个字符的位置,所有的组合也按字典顺序。

注意哦!输出时,每个数字需要 3 个场宽。以 C++ 为例,你可以使用下列代码:

复制代码
cout << setw(3) << x;

输出占 3 个场宽的数 x。注意你需要头文件 iomanip

输入输出样例

输入 #1复制

复制代码
5 3 

输出 #1复制

复制代码
  1  2  3
  1  2  4
  1  2  5
  1  3  4
  1  3  5
  1  4  5
  2  3  4
  2  3  5
  2  4  5
  3  4  5

我现在再次重复一遍:写递归,请你放空你的脑袋,然后用样例,画出一个草图,然后用最简单的(最暴力的)思路去想。不要想太细,太复杂。等你把递归的框架搭建完了,再去思考边界。

认真看题目啊喂,由于题目要求,每一组数必须是从小到大的排列,所以当第二个数是5的时候,后面没有比5更大的,所以这种组合就不存在。

第一步,让我们轻轻画一个草图:

这个就是以1为开头的,所有排列组合

再说一遍:递归题,不要想太多,画出一个例子就可以了,想太多,越想越乱。

第二步,根据图像想一个巨巨巨巨巨朴素的思路(最暴力的)

我们从1开始往下找,一共要找3个数字.

由于这个图像每一层左边到右边逐渐是增加的,所以.....

先找1的下一层的最左边:1 , 2

找2 的下一层的最左边: 1 ,2 ,3

3没有下一层,所以不断右移动:1,2,4------------1,2,5

5就到头了,然后回到上一层

2的下一层找完了,所以不断向右移动,1,3------

对于1,3继续重复这个步骤

ok,思路非常简单,我想你们应该也能想到这样做,如果大体能看懂,那也很不错了,相信阅读完本栏目之后,你能不害怕递归。

直接上代码就完事了:

cpp 复制代码
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<cstdio>
#include<cmath>
#include<string>
#include<cstring>
#include<string>
#include<algorithm>
#include<vector>
#include<cctype>
#include<map>
#include<set>
#include<queue>
#include<numeric>
#include<iomanip>
using namespace std;
const int N = 30;
int t[N];
int flag[N];
int n, r;
void dfs(int x,int y) {

	if (y > r ) { 当前序列里面的数字个数大于r的时候,就停止

		for (int i = 1; i <= r; i++) { 打印答案
			cout << setw(3) << t[i];
		}

		cout << endl;
		return;
	}
	for (int i = x ; i <= n; i++)   从x开始,保证后面存进来的每一个数都大于x

		if (flag[i] == 0 ) {  如果i被标记过了,那么我们就不管i,如果没有,就把i加入到序列里面
			flag[i] = 1;   标记i
			t[y] = i;      把i加入到序列里面
			dfs(i + 1, y + 1);   递归下一个数
			flag[i] = 0;       递归结束之后,恢复标记
		}
}
int main() {
	cin >> n>>r;
	dfs(1, 1); //递归从1开始,第二个1代表序列里面只有1个数字
}

多么简单的一道递归啊。

相关推荐
代码游侠2 小时前
日历的各种C语言实现方法
c语言·开发语言·学习·算法
草莓熊Lotso2 小时前
unordered_map/unordered_set 使用指南:差异、性能与场景选择
java·开发语言·c++·人工智能·经验分享·python·网络协议
咔咔咔的4 小时前
1930. 长度为 3 的不同回文子序列
c++
春日见6 小时前
丝滑快速拓展随机树 S-RRT(Smoothly RRT)算法核心原理与完整流程
人工智能·算法·机器学习·路径规划算法·s-rrt
Code小翊6 小时前
”回调“高级
算法·青少年编程
云里雾里!6 小时前
力扣 977. 有序数组的平方:双指针法的优雅解法
算法·leetcode·职场和发展
一只侯子9 小时前
Face AE Tuning
图像处理·笔记·学习·算法·计算机视觉
Cinema KI9 小时前
吃透C++继承:不止是代码复用,更是面向对象设计的底层思维
c++
jianqiang.xue9 小时前
别把 Scratch 当 “动画玩具”!图形化编程是算法思维的最佳启蒙
人工智能·算法·青少年编程·机器人·少儿编程
不许哈哈哈10 小时前
Python数据结构
数据结构·算法·排序算法