题目描述
从 1\sim n1∼n这 n (n \leq 16)(n≤16) 个整数中随机选取任意多个,输出所有可能的选择方案。
输入描述:
一个整数n。
输出描述:
每行一种方案。同一行内的数必须升序排列,相邻两个数用恰好1个空格隔开。对于没有选任何数的方案,输出空行。本题有自定义校验器(SPJ),各行(不同方案)之间的顺序任意。
这道题有多种解法,这里只介绍状态压缩版:
状态压缩的特性:
可以枚举所有选与不选的情况。
实例:
不难发现题目输出的结果都为2^n:
当n为2时输出:
000->/n
001->1
010->2
011->1 2
当n为3时输出:
000->/n
001->1
010->2
100->3
011->1 2
101->1 3
110->2 3
111->1 2 3
C++状压递归版:
#include <iostream>
using namespace std;
int N;
void dfs(int n, int state)//n为当前枚举到的数,state是记录哪些数被选
{
if (N == n) {
for (int i = 0; i < n; i++)
if (state >> i & 1)
cout << i + 1 << " ";
cout << endl;
return;
}
dfs(n + 1, state);//不用n这个数
dfs(n + 1, state | (1 << n));//用n这个数
}
int main() {
cin >> N;
dfs(0, 0);
}虽然题目是递归,但我从小就不是一个唯命是从的人
所以
C++状压非递归版:
#include <iostream>
using namespace std;
int main() {
int n;
cin >> n;
//state表示每一种状态
for (int state = 0; state < (1 << n); state++)
{
//用i遍历整个state并输出
for (int i = 0; i < n; i++)
if (state >> i & 1)
cout << i + 1 << " ";
cout << endl;
}
return 0;
}我觉得每到题不一定只有一种答案呢,以上只给出两种还有例如vector枚举来解的等等......

京公网安备 11010502036488号