【题目】
从 这
个整数中随机选取任意多个,输出所有可能的选择方案。
每行一种方案。同一行内的数必须升序排列,相邻两个数用恰好1个空格隔开。对于没有选任何数的方案,输出空行。本题有自定义校验器(SPJ),各行(不同方案)之间的顺序任意。
【题解】
DFS,即深度优先搜索。深度、优先、搜索。
即可以把单行的输出联想成一条线,而输出的具体内容就是一颗一颗的珍珠。我们要思考的,就是怎么把这一颗颗珍珠串进这根线上。题目要求的是个数中取任意数按升序排列输出,各行顺序任意。在现实之中,如果我们用手写出来的思路,倒也是有很多种,比如:先从1开始找,
这样一个个写下去;还有就是从1开始找,
这样写下去。这个题解,我们来实现一下第二个输出方法。如果是这种输出方法的话,我们就需要让其第一个输出的就是选的数的数量最小的1、2、3、4...,也就是说在dfs遍历到最低层的时候,把需要输出的结果输出。而这就需要我们把深度遍历的优先定为选择的数的个数。这样的话,我们可以把选择珍珠(数字)的方法分为两种:选和不选。而要实现优先输出选择的数量小的,就需要先遍历不选的情况,让其尽可能的不选,直到最后没有办法了,才选了一个,再直到没有办法选一个了,才选两个,一直这样下去。如果看了题解还不明白的,可以结合下面的代码理解一下。
时间复杂度:
#include<iostream> #include<cstring> #include<sstream> #include<string> #include<cstdio> #include<cctype> #include<vector> #include<queue> #include<cmath> #include<stack> #include<list> #include<set> #include<map> #include<algorithm> #define fi first #define se second #define MP make_pair #define P pair<int,int> #define PLL pair<ll,ll> #define lc (p<<1) #define rc (p<<1|1) #define MID (tree[p].l+tree[p].r)>>1 #define Sca(x) scanf("%d",&x) #define Sca2(x,y) scanf("%d%d",&x,&y) #define Sca3(x,y,z) scanf("%d%d%d",&x,&y,&z) #define Scl(x) scanf("%lld",&x) #define Scl2(x,y) scanf("%lld%lld",&x,&y) #define Scl3(x,y,z) scanf("%lld%lld%lld",&x,&y,&z) #define Pri(x) printf("%d\n",x) #define Prl(x) printf("%lld\n",x) #define For(i,x,y) for(int i=x;i<=y;i++) #define _For(i,x,y) for(int i=x;i>=y;i--) #define FAST_IO std::ios::sync_with_stdio(false), cin.tie(0), cout.tie(0); #define STOP system("pause") #define ll long long const int INF=0x3f3f3f3f; const ll INFL=0x3f3f3f3f3f3f3f3f; const double Pi = acos(-1.0); using namespace std; template <class T>void tomax(T&a,T b){ a=max(a,b); } template <class T>void tomin(T&a,T b){ a=min(a,b); } const int N=16; int out[20],n; void dfs(int num,int k){ if(num==n+1){ for(int i=1;i<k;i++) printf("%d ",out[i]); puts(""); return ; } dfs(num+1,k); out[k]=num; dfs(num+1,k+1); } int main(){ Sca(n); dfs(1,1); }