这题其实就是搜索+回溯(可是我仍然写了2小时)
这个题呢,我跟楼下们的思路有一些不一样:
首先,第一组排列一定是1~k(前k个元素),于是进行一个预处理;
接下来开始搜:
先从第k个元素搜,搜完前k-1个元素为1~k时最后一个元素的所有情况(边搜边记);
搜完了(前k个元素填满了或任意一个元素>n了或前k个元素未填满,但目前元素已经到n了(下一步就没了))(第一种情况下输出)就回溯;
共搜k次,每次范围向前1个元素,初始值为x(目前在搜第几个元素)
搜完了就好了。
上代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
| #include<iostream> #include<cstdio> #include<iomanip> #include<cstring> using namespace std; int n,k,x,a[25],d; void print(){ for (int i=1;i<=k;i++) printf ("%3d",a[i]); printf ("\n"); } void dfs(){ if (x>k){print();return;} if (x<k&&d==n){return;}
for (int i=1;i+d<=n;i++){
d+=i; a[x++]=d; dfs(); x--; d-=i; } } int main(void){ cin>>n>>k; for (int i=1;i<=k;i++)a[i]=i; x=k; d=k-1; while (x){ dfs(); x--; d=x; } }
|
我的程序比楼下们省空间,因为我不用判重。所以,希望能过~