题解: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);
}
posted @ 2024-12-02 13:38  困死了要  阅读(17)  评论(0编辑  收藏  举报