题目链接:https://www.acwing.com/problem/content/94/
题目:
- 递归实现指数型枚举
题目
提交记录
讨论
题解
视频讲解
从 1~n 这 n 个整数中随机选取任意多个,输出所有可能的选择方案。
输入格式
输入一个整数n。
输出格式
每行输出一种方案。
同一行内的数必须升序排列,相邻两个数用恰好1个空格隔开。
对于没有选任何数的方案,输出空行。
本题有自定义校验器(SPJ),各行(不同方案)之间的顺序任意。
数据范围
1≤n≤15
输入样例:
3
输出样例:
3
2
2 3
1
1 3
1 2
1 2 3
题解思路1(二进制表示法):
因为我们可以选n位数,一个数可以选也可以不选,那么一共有2 ^ n种选法。我们需要做的就是列举出每一种状态。
那么我们就可以直接用一个n位的二进制数进行模拟状态,每次去判断对应位置上的的二进制是否为1,若为1,则输出对应所表示的数字。
AC代码:
#include <iostream>
#include <cstdio>
using namespace std;
int main(void) {
// freopen("in.txt", "r", stdin);
int n;
scanf("%d", &n);
for(int i = 0; i < 1 << n; i ++) {
int b = i, a = 1;
while(b) {
if(b & 1) printf("%d ", a);
a ++;
b >>= 1;
}
puts("");
}
// fclose(stdin);
return 0;
}
解题思路2(搜索法):
我们可以直接从1开始去搜索,每次出口设置为2个,一个为不选当前的数,一个是选当前的数;
最后当我们的x = n + 1的时候就直接输出我们搜索过程种选取的数字,可以用vector来存。
注意点:
1.没有选取任何数字的时候也要输出一个空行
AC代码:
#include <iostream>
#include <cstdio>
#include <vector>
using namespace std;
vector<int> a;
int n;
inline void dfs(int x) {
if(x == n + 1) {
if(a.size() == 0) {
puts("");
return;
}
for(int i = 0; i < a.size(); i ++)
printf("%d ", a[i]);
puts("");
return ;
}
//不选当前的数
dfs(x + 1);
//选当前的数字
a.push_back(x);
dfs(x + 1);
//恢复现场
a.pop_back();
}
int main(void) {
scanf("%d", &n);
dfs(1);
return 0;
}