题解:AT_abc382_d [ABC382D] Keep Distance
题目传送门
思路
老样子,先看数据范围。
- \(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);
}