题解:AT_abc382_d [ABC382D] Keep Distance

本文同步发布至洛谷

题解报告

题目翻译

可以理解为我们要输出 n n n 个数,其中两两差距必须大于等于 10 10 10。

解题思路

首先这道题的第一个数肯定要从1开始,这是没有问题的对吧。

然后我们又发现最大的 n n n 只有 12 12 12,那么我们完全可以打暴力来枚举所有的情况(注:这里要按照字典序枚举),也就是说,只要我们能够使每次所枚举的值都是有意义的就可以了。

那么怎么做呢?

这是非常简单的,我们只需要确定一个数的上下边界就可以了。

设一个数为 x x x,他的上一个数为 l a s t last last,当前为第 k k k 个数,我们不难发现:

l a s t + 10 ≤ x ≤ m − ( n − k ) × 10 last+10 \le x \le m-(n-k) \times 10 last+10≤x≤m−(n−k)×10

那么我们完全就可以直接 dfs 来枚举,并且使每次的值都是满足上述条件的就可以了。

注:这里不能直接存储下来,因为会爆空间,所以我们可以 dfs 两次,第一次求 c n t cnt cnt,第二次来枚举。

cpp 复制代码
#include <bits/stdc++.h>
using namespace std;

int n,m;
int v[20]={-9};//注意一下初值的问题
long long cnt;

void dfs1(int x){
	if (x==n+1){
		cnt++;
		return;
	}
	for (int i=v[x-1]+10;i<=m-(n-x)*10;i++){
		v[x]=i;
		dfs1(x+1);
	}
	return;
}

void dfs2(int x){
	if (x==n+1){
		for (int i=1;i<=n;i++){
			cout<<v[i]<<" ";
		}
		cout<<endl;
		return;
	}
	for (int i=v[x-1]+10;i<=m-(n-x)*10;i++){
		v[x]=i;
		dfs2(x+1);
	}
	return;
}

int main() {
	cin>>n>>m;
	dfs1(1);
	cout<<cnt<<endl;
	dfs2(1);
	return 0;
}
相关推荐
半夢半醒121 分钟前
[原创]《C#高级GDI+实战:从零开发一个流程图》第章:增加菱形、平行四边形、圆角矩形,文本居中显示
算法·c#·流程图
Jerry29 分钟前
LeetCode 90. 子集 II
算法
机器学习之心1 小时前
CCD实验设计+SVM代理建模+改进NSGA-II工艺参数多目标优化,MATLAB代码
算法·支持向量机·matlab·多目标优化
SOLECA_1 小时前
Ascend C 算子实战(二)|SigmoidCustom 逐元素激活算子完整开发指南
算法
Jerry1 小时前
LeetCode 78. 子集
算法
DuHz2 小时前
论文解读:用于数据分析的极值点对称模态分解方法 (Extreme-point Symmetric Mode Decomposition,ESMD)
论文阅读·算法·信息与通信·信号处理
HZZD_HZZD2 小时前
用电负荷聚类分析实战:基于`scikit-learn`的`K-Means`与`DBSCAN`双算法对比、`PCA`降维可视化与智能电表负荷画像全流程
算法·scikit-learn·kmeans
MIngYaaa5202 小时前
2026暑期牛客多校1 2026-7-17
数据结构·算法
wabs6662 小时前
关于图论【卡码网107.寻找存在的路线的思考】
数据结构·算法·图论
半兽先生2 小时前
大模型技术开发与应用——4.大模型提示词工程实战
人工智能·算法