题目描述
如果一个奇数满足以下两个条件之一:
- 以5结尾
- 各个数位相加的和是3的倍数
则称它是一个"智数"
前555个"智数"分别为{3,5,9,15,21}
现在智乃想要你给升序排序第k个"智数"
输入描述:
第一行输入一个正整数T(1≤T≤10e5)表示测试用例的组数 对于每组测试用例,在一行中输入一个正整数k(1≤k≤10e9)
输出描述:
对于每个问题,输出一行一个正整数,表示问题的答案
示例1
输入
5 1 2 3 4 5
输出
3 5 9 15 21
示例2
输入
1 1000000000
输出
4285714285
关键原理分析
-
周期性观察:
-
通过观察前几个智数
{3, 5, 9, 15, 21, 25, 27}
,发现它们以30为周期重复出现。 -
每增加30,新的智数由基数组
a
中的元素加上30的倍数生成(如3→33→63
,5→35→65
)。
-
-
数学推导:
-
奇数的性质:若
x
是奇数,则x + 30
仍为奇数。 -
条件保持:
-
以5结尾:若
x
以5结尾,则x + 30
仍以5结尾(如5 → 35
)。 -
数位和是3的倍数:若
x
的数位和是3的倍数,则x + 30
的数位和增加3(如3 → 33
,数位和3 → 6)。
-
-
-
周期验证:
-
基数组
a
:前7个智数为{3,5,9,15,21,25,27}
,共7个。 -
每30个数生成7个新智数:例如,
3 + 30 = 33
,5 + 30 = 35
,依此类推,均满足智数条件。
-
代码逻辑
-
预处理基数组
a
:-
存储前7个智数,作为周期性重复的基准值。
-
-
计算第k个智数:
-
k减1:将输入调整为从0开始的索引。
-
周期计算:
-
chu = k // 7
:确定完整周期的个数。 -
yu = k % 7
:确定当前周期内的偏移量。
-
-
结果生成:
chu * 30 + a[yu]
,即基准值加上周期倍数。
-
正确性验证
-
示例验证:
-
k=1
→k-1=0
→chu=0, yu=0
→0*30 + 3 = 3
。 -
k=7
→k-1=6
→chu=0, yu=6
→0*30 + 27 = 27
。 -
k=8
→chu=1, yu=0
→30 + 3 = 33
(第8个智数)。
-
-
周期性保持:
-
基数组中的每个数加30后仍满足智数条件,确保后续所有数正确。
-
复杂度与优势
-
时间复杂度:
O(1)
每查询,远优于二分法的O(log(1e18))
。 -
适用场景:高效处理大范围查询(如
k ≤ 1e9
),通过预计算避免重复计算。
#include<bits/stdc++.h> using namespace std; int a[22]={3,5,9,15,21,25,27}; int main(){ int n; int t; cin>>t; while(t--){ int k; cin>>k; k--; long long chu=k/7,yu=k%7; cout<<chu*30+a[yu]<<'\n'; } }