第一次写题解,如有不对的地方还请各位指正。

  • 首先说一下这个题目的坑点。
  1. 可以不选任何一个数,对于没有选任何数的方案,输出空格。
  2. 自定义校检器(SPJ)在自测时时没有用的。
  • 然后是算法的部分。
  1. 按照题目要求,升序打印出所有组合,所以可以从小到大依次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;
    }

  2. 当然我们也可以不设立数组,用二进制把状态压缩并记录,由于最多有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;
    }