题解: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;
}
相关推荐
信奥卷王3 小时前
[GESP202609 六级] 分树规划
算法
夏幻灵3 小时前
LeetCode 21:合并两个有序链表——双指针与哑节点详解
算法·leetcode·链表
徐小黑ACG5 小时前
Golang 基础05 结构体struct
开发语言·算法·golang
Navigator_Z5 小时前
LeetCode //C - 1286. Iterator for Combination
c语言·算法·leetcode
北极有牛6 小时前
cpp学习笔记--常量指针
java·开发语言·算法
GPU实战笔记6 小时前
云端 GPU 训练的账户余额提醒:它能说明什么,不能说明什么?
深度学习·算法·成本管理·gpu云计算·云端训练
浮链序6 小时前
怎么证明"你这个模型是偷我的"——把蒸馏变成取证工具
算法·安全·llm
小O的算法实验室6 小时前
IEEE TMC,面向异构物联网的多目标量子行为拓扑优化算法
算法
liliangcsdn7 小时前
派息率指标的应用探索和分析
大数据·算法