第一次写题解,如有不对的地方还请各位指正。
- 首先说一下这个题目的坑点。
- 可以不选任何一个数,对于没有选任何数的方案,输出空格。
- 自定义校检器(SPJ)在自测时时没有用的。
- 然后是算法的部分。
- 按照题目要求,升序打印出所有组合,所以可以从小到大依次dfs(这样可以保证选了一个数后,以后选择的数都比它要大),每次dfs一个数的时候,可以选择这个数,也可以不选这个数,dfs到n时停止,之后打印选择的所有数,所以我们需要一个flag数组在打印时judge这个数有没有被选择。注意每次打印完成后需要换行,这样就算没有选择数据,也可以打印换行。
#include <iostream> using namespace std; int n; int flag[17] = {0}; void dfs(int a) { if (a == n) { for (int i = 1; i <= n; i++) { if (flag[i]) { cout << i << ' '; } } cout << endl; return; } flag[a + 1] = 0; dfs(a + 1); flag[a + 1] = 1; dfs(a + 1); } int main() { cin >> n; dfs(0); return 0; }
- 当然我们也可以不设立数组,用二进制把状态压缩并记录,由于最多有16个数据,所以状态共有2^16个,可以用int类型储存。具体细节看代码吧OvO
#include <iostream> using namespace std; int n; void dfs(int a, int state) { if (a == n) { for (int i = 1; i <= n; i++) { if (state >> i & 1) { cout << i << ' '; } } cout << endl; return; } dfs(a + 1, state); //不选a + 1这个数 dfs(a + 1, state | 1 << a + 1); //选a + 1这个数 } int main() { cin >> n; dfs(0, 0); return 0; }