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

news/2024/7/20 22:51:22 标签: 算法, c++, 深度优先

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

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

上题干:

题目描述

排列与组合是常用的数学方法,其中组合就是从 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个数字.

先找下一层最左边的,是2,此时序列就是1,2。

由于我们要字典序(不知道字典序是什么的,看一下样例给的答案。)(也就是 1 2 3 必须要在 1 2 4 前面, 2 3 4 必须 要在 2 3 5前面,这样的排序,不过多解释)从小到大,

所以我们直接递归到下一层,从下一层的最左边开始(最左边最小),

此时的序列就是1,2,3。

打印序列,向逐渐增大移动,序列变为1,2,4  继续移动,序列变成1,2,5

当没有数了之后,回到上一层

当 2的下一层都找完了,,继续向2这一层数字增大的方向走,也就是1,2变成1,3。

重复此过程。

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

直接上代码就完事了:

#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个数字
}

多么简单的一道递归啊。 

 


http://www.niftyadmin.cn/n/5211943.html

相关文章

qgis添加arcgis的FeatureServer

左侧浏览器-ArcGIS要素服务器-新建连接 http://sampleserver6.arcgisonline.com/arcgis/rest/services/ 展开-双击即可

考过了PMP,面试的时候应该怎么办?

近期喜番在后台收到了很多同学们的私信&#xff0c;表示自己已经过了8月份的PMP考试&#xff0c;开始着手往项目管理岗位转型&#xff0c;但是对于项目管理岗位的面试却一筹莫展。放轻松&#xff0c;大家的需求喜番都了解了&#xff0c;喜番给大家总结了一些项目经理在面试的时…

Vue服务端渲染——同构渲染

Vue.js 可以用于构建客户端应用程序&#xff0c;组件的代码在浏览器中运行&#xff0c;并输出 DOM 元素。同时&#xff0c;Vue.js 还可以在 Node.js 环境中运行&#xff0c;它可以将同样的组件渲染为字符串并发送给浏览器。这实际上描述了 Vue.js 的两种渲染方式&#xff0c;即…

C语言-指针讲解(3)

文章目录 1.字符指针变量1.1 字符指针变量类型是什么1.2字符指针变量的两种使用方法&#xff1a;1.3字符指针笔试题讲解1.3.1 代码解剖 2.数组指针变量2.1 什么是数组指针2.2 数组指针变量是什么&#xff1f;2.2.3 数组指针变量的举例 2.3数组指针和指针数组的区别是什么&#…

IOS免签封装打包苹果APP的方法

IOS免签app封装打包苹果APP的方法如下&#xff1a; 准备一个未签名的IPA文件。获取一个企业证书或个人证书&#xff0c;用于签名IPA文件。将证书添加到Keychain Access中。安装iOS App Signer&#xff08;可以在网上找到相关下载链接&#xff09;。打开iOS App Signer&#xf…

如何获取item_recommend-获取推荐商品列表api接口

获取item_recommend-获取推荐商品列表API接口的步骤可能会因电商平台和具体的使用情况而有所不同。以下是一般的步骤&#xff1a; 了解API接口的使用规则和要求&#xff1a;在获取API接口之前&#xff0c;需要了解该API接口的使用规则和要求&#xff0c;包括API的调用方式、参…

Go事件管理器:简单实现

关注公众号【爱发白日梦的后端】分享技术干货、读书笔记、开源项目、实战经验、高效开发工具等&#xff0c;您的关注将是我的更新动力&#xff01; 在编程中&#xff0c;事件管理器是一种常见的工具&#xff0c;用于通过通知来触发操作。在Go语言中&#xff0c;我们可以通过创建…

嵌入式FPGA IP正在发现更广阔的用武之地

作者&#xff1a;郭道正, Achronix Semiconductor中国区总经理 在日前落幕的“中国集成电路设计业2023年会暨广州集成电路产业创新发展高峰论坛&#xff08;ICCAD 2023&#xff09;”上&#xff0c;Achronix的Speedcore™嵌入式FPGA硅知识产权&#xff08;eFPGA IP&#xff09…