解题思路
1. 核心观察:智数的周期规律
智数定义是奇数且满足以下任一条件:
- 以 5 结尾(即 mod 10 = 5);
- 各位数字之和是 3 的倍数(等价于自身是 3 的倍数,因为一个数是 3 的倍数 ↔ 各位和是 3 的倍数)。
通过枚举前若干智数,发现其分布存在固定周期:
- 先列出智数序列(升序):3、5、9、15、21、25、27、33、35、39、45、51、55、57、...
- 观察间隔:从 3 开始,每 7 个智数为一组,每组内的智数与下一组对应智数的差值固定为 30(即周期长度 = 30)。第 1 组(k=1~7):3、5、9、15、21、25、27第 2 组(k=8~14):33(3+30)、35(5+30)、39(9+30)、45(15+30)、51(21+30)、55(25+30)、57(27+30)第 3 组(k=15~21):63(3+60)、65(5+60)、69(9+60)、...(以此类推)
2. 周期规律验证
周期长度 30 的本质:
- 3 的倍数的奇数:公差为 6(3、9、15、21、27、33...);
- 以 5 结尾的奇数:公差为 10(5、15、25、35、55...);
- 两者的最小公倍数为 30,因此智数的分布周期为 30,且每个周期内恰好包含 7 个不重复的智数。
3. 公式推导
基于周期规律,第 k 个智数可通过以下步骤计算:
- 索引转换:将 k 从 “1-based” 转为 “0-based”(k--),方便取模计算;
- 分组计算:每组有 7 个智数,通过
t = k / 7得到第 k 个智数所在的组号(从 0 开始); - 组内定位:通过
r = k % 7得到第 k 个智数在组内的索引(0~6); - 结果计算:每组的基准偏移量为
30 * t,加上组内对应索引的智数(预存于数组),即为答案。
ACnode
#include <bits/stdc++.h>
using namespace std;
#define int long long //避免溢出
// 预存一个周期内(7个)智数的基础值(第1组的7个智数)
int arr[7] = {3, 5, 9, 15, 21, 25, 27};
void solve()
{
int k;
cin >> k;
k--; // 1-based转0-based索引,方便取模
int t = k / 7; // 计算所在组号(0开始),每组7个智数
int r = k % 7; // 计算组内索引(0~6)
// 每组偏移量为30*t,加上组内对应基础值
cout << 30 * t + arr[r] << endl;
}
signed main()
{
int qwq = 1;
cin >> qwq;
while (qwq--)
{
solve(); // 处理每组测试
}
return 0;
}
时间复杂度与空间复杂度
- 时间复杂度:O (T),每组测试用例仅需 O (1) 计算,T=1e5 时无压力;
- 空间复杂度:O (1),仅用固定大小的数组存储 7 个基础值,无额外空间消耗。

京公网安备 11010502036488号