ACM算法--枚举方法(指数枚举,组合枚举)模板
// 递归实现指数型枚举
vector<int> chosen;
void calc(int x) {
if (x == n + 1) {
for (int i = 0; i < chosen.size(); i++)
printf("%d ", chosen[i]);
puts("");
return;
}
calc(x + 1);
chosen.push_back(x);
calc(x + 1);
chosen.pop_back();
}
// 递归实现组合型枚举
vector<int> chosen;
void calc(int x) {
if (chosen.size() > m || chosen.size() + (n - x + 1) < m) return;
if (x == n + 1) {
for (int i = 0; i < chosen.size(); i++)
printf("%d ", chosen[i]);
puts("");
return;
}
calc(x + 1);
chosen.push_back(x);
calc(x + 1);
chosen.pop_back();
}
// 递归实现排列型枚举
int order[20];
bool chosen[20];
void calc(int k) {
if (k == n + 1) {
for (int i = 1; i <= n; i++)
printf("%d ", order[i]);
puts("");
return;
}
for (int i = 1; i <= n; i++) {
if (chosen[i]) continue;
order[k] = i;
chosen[i] = 1;
calc(k + 1);
chosen[i] = 0;
order[k] = 0;
}
}
// 模拟机器实现,把组合型枚举改为非递归
vector<int> chosen;
int stack[100010], top = 0, address = 0;
void call(int x, int ret_addr) { // 模拟计算机汇编指令call
int old_top = top;
stack[++top] = x; // 参数x
stack[++top] = ret_addr; // 返回地址标号
stack[++top] = old_top; // 在栈顶记录以前的top值
}
int ret() { // 模拟计算机汇编指令ret
int ret_addr = stack[top - 1];
top = stack[top]; // 恢复以前的top值
return ret_addr;
}
int main() {
int n, m;
cin >> n >> m;
call(1, 0); // calc(1)
while (top) {
int x = stack[top - 2]; // 获取参数
switch (address) {
case 0:
if (chosen.size() > m || chosen.size() + (n - x + 1) < m) {
address = ret(); // return
continue;
}
if (x == n + 1) {
for (int i = 0; i < chosen.size(); i++)
printf("%d ", chosen[i]);
puts("");
address = ret(); // return
continue;
}
call(x + 1, 1); // 相当于calc(x + 1),返回后会从case 1继续执行
address = 0;
continue; // 回到while循环开头,相当于开始新的递归
case 1:
chosen.push_back(x);
call(x + 1, 2); // 相当于calc(x + 1),返回后会从case 2继续执行
address = 0;
continue; // 回到while循环开头,相当于开始新的递归
case 2:
chosen.pop_back();
address = ret(); // 相当于原calc函数结尾,执行return
}
}
}
ACM算法--枚举方法(指数枚举,组合枚举)模板的更多相关文章
- .NET 基础一步步一幕幕[方法、结构、枚举]
方法.结构.枚举 方法: 将一堆代码进行重用的一种机制. 语法: [访问修饰符] 返回类型 <方法名>(参数列表){ 方法主体: } 返回值类型:如果不需要写返回值,写void 方法名:P ...
- iOS 开发--NSMutableArray使用枚举方法
可变数组也可以使用枚举方法, 我们在这里提供了两种枚举方法, 一个是正序枚举, 一个是倒序枚举, 在正序枚举中, 元素的个数和顺序都是不可以修改的, 但是在倒序枚举中却可以修改, 这有些耐人寻味. 涉 ...
- swift_枚举 | 可为空类型 | 枚举关联值 | 枚举递归 | 树的概念
***************可为空的类型 var demo2 :we_demo = nil 上面这个代码串的语法是错的 为什么呢, 在Swift中,所有的类型定义出来的属性的默认值都不可以是nil ...
- java枚举与.net中的枚举区别
通过一段时间的项目实践,发现java中的枚举与.net中的枚举有很大的差别,初期造成了我对java中的枚举一些错误理解及部分有缺陷的应用,其实追其原因还是因为我会习惯性的认为java的枚举在作用以及定 ...
- C#的枚举数(Enumerator)和可枚举类型(Enumerable)
数组可以被foreach语句遍历数组中的元素,原因是数组可以按需提供一个叫做枚举数(enumerator)的对象.枚举数可以依次返回请求的数组的元素. 对于有枚举数的类型而言,必须有一个方法来获取它们 ...
- C# 给枚举定义DescriptionAttribute,把枚举转换为键值对
在C#中,枚举用来定状态值很方便,例如我定义一个叫做Season的枚举 public enum Season { Spring = 1, Summer = 2, Autumn = 3, Winter ...
- Java枚举enum以及应用:枚举实现单例模式
枚举作为一个常规的语言概念,一直到Java5才诞生不得不说有点奇怪,以至于到现在为止很多程序员仍然更喜欢用static final的形式去命名常量而不使用,一般情况下,Java程序员用这种方式去实现枚 ...
- 【C/C++开发】C++之enum枚举量声明、定义、使用与枚举类详解与枚举类前置类型声明
众所周知,C/C++语言可以使用#define和const创建符号常量,而使用enum工具不仅能够创建符号常量,还能定义新的数据类型,但是必须按照一定的规则进行,下面我们一起看下enum的使用方法. ...
- ACM,算法
ACM,算法 描述 最近Topcoder的XD遇到了一个难题,倘若一个数的三次方的后三位是111,他把这样的数称为小光棍数.他已经知道了第一个小光棍数是471,471的三次方是104487111,现在 ...
- 机器学习-牛顿方法&指数分布族&GLM
本节内容 牛顿方法 指数分布族 广义线性模型 之前学习了梯度下降方法,关于梯度下降(gradient descent),这里简单的回顾下[参考感知机学习部分提到的梯度下降(gradient desce ...
随机推荐
- (29)ASP.NET Core3.1 Swagger(OpenAPI)
1.什么是Swagger/OpenAPI? Swagger是一个与语言无关的规范,用于描述REST API.因为Swagger项目已捐赠给OpenAPI计划,所以也叫OpenAPI.它允许计算机和人员 ...
- python CGI 编程实践
文章更新于:2020-03-05 注1:安装 python 参见: python 的安装使用和基本语法 注2:配置 web 环境参见: Windows&linux使用集成环境搭建 web 服务 ...
- Springboot2(二)通过微信熟悉熟悉Spring-boot yml配置文件
前言:Spring-boot的yml配置文件,这里就不在借助人.狗介绍了,试试套下微信! 创建yml文件 值得注意的是下图中有三种命名方法,前两种是对的,且第二种必须是横线而不是下划线! yml文件的 ...
- pycharm 永久激活方法
打开终端,执行: cd /etc/ sudo vim hosts 在最后一行加上: 0.0.0.0 account.jetbrains.com 打开pycharm,选择Activation Code ...
- 别人用钱,而我用python爬虫爬取了一年的4K高清壁纸
前言 本文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理. PS:如有需要Python学习资料的小伙伴可以加点击下方链接自行获取htt ...
- D - Catch That Cow BFS
农夫知道一头牛的位置,想要抓住它.农夫和牛都于数轴上 ,农夫起始位于点 N(0<=N<=100000) ,牛位于点 K(0<=K<=100000) .农夫有两种移动方式: 1. ...
- 数据结构与算法--树(tree)结构
树 二叉树 遍历原则:前序遍历是根左右, 中序遍历是左根右,后序遍历是左右根. 二叉搜索树 特点:对于树中的每个节点X,它的左子树中所有节点的值都小于X,右子树中所有节点的值都大于X. 遍历:采取二叉 ...
- JavaScript中的作用域和作用域链(边学边写)[看着别人的博客纯手敲]
作用域是JavaScript最重要的概念之一,想要学好JavaScript就需要理解JavaScript作用域和作用域的工作原理.今天这篇文章对JavaScript作用域和作用域链简单的介绍,希望能帮 ...
- vue2.x学习笔记(二十)
接着前面的内容:https://www.cnblogs.com/yanggb/p/12631279.html. 循环引用 递归组件 组件是可以在它们自己的模板中调用自身的,不过它们只能通过[name] ...
- SMTP发邮件(直接可用)实例
string file = "邮件测试.txt";//放在Debug下的一个txt文件. MailAddress from = new MailAddress("自己的邮 ...