题目传送门
思路
老样子,先看数据范围。
- \(2 \leq N \leq 12\)
- \(10N - 9 \leq M \leq 10N\)
加上限时五秒钟,所以可以放心的写。
设 \(X\) 为输出的倒数第 \(Y\) 个数,\(Z\) 为上一个数的值。
观察样例,确定 \(X\) 的取值范围是 \((Z+10) \sim (M-Y \times 10+10)\) 这样我们就可以用递归来写这道题了。
按照题目要求,先统计数量。
首先,按照先前求出来的范围枚举每个位置上的值。
每一个数字至少要比前一个大 10 ,当它统计出来的数字已经大于了它所限制的最大值,就提前返回。
如果它的每一个位置上都填上了值,并且最后一位的值满足题目搜给的要求,就统计。
void qq1(int x,int y)
{if(y>m)return ;if(x==0){s++;return ;}for(int i=y+10;i<=m-x*10+10;i++)qq1(x-1,i);
}
然后按照同样的方法再递归一次。
但是如果它的每一个位置上都填上了值,并且最后一位的值满足题目搜给的要求,不再统计,直接输出。
void qq(int x,int y)
{if(y>m)return ;if(x==0){for(int i=n;i>=1;i--)cout<<h[i]<<" ";cout<<endl;return ;}for(int i=y+10;i<=m-x*10+10;i++){h[x]=i;qq(x-1,i);}
}
代码
#include<bits/stdc++.h>
using namespace std;
int n,m;
int h[20];
int s=0;
void qq1(int x,int y)
{if(y>m)return ;if(x==0){s++;return ;}for(int i=y+10;i<=m-x*10+10;i++)qq1(x-1,i);
}
void qq(int x,int y)
{if(y>m)return ;if(x==0){for(int i=n;i>=1;i--)cout<<h[i]<<" ";cout<<endl;return ;}for(int i=y+10;i<=m-x*10+10;i++){h[x]=i;qq(x-1,i);}
}
int main()
{ios::sync_with_stdio(false);cin.tie(),cout.tie();cin>>n>>m;qq1(n,-9);cout<<s<<endl;qq(n,-9);
}