2024 GESP五级「奇妙数字」深度解析:高效解题代码与数学逻辑揭秘(洛谷B4070)
一、题目解读
2024年GESP(青少年编程能力等级测试)五级题目「奇妙数字」(对应洛谷平台题目B4070),要求选手根据特定规则计算输入数字的“奇妙值”。题目核心在于挖掘数字的数学特性,结合质因数分解与公式推导,考验算法设计与数学逻辑的结合能力。理解题目本质是解题的第一步,需明确“奇妙数字”的定义与计算规则。
二、解题思路
采用“质因数分解+数学公式推导”的双层策略:
1. 质因数分解:通过优化筛法(仅处理奇数+特判2)高效分解输入数字 n 的质因数,存储为键值对(质因数/指数)。
2. 数学公式计算:对每个质因数指数 e,利用公式 k = floor((sqrt(8e + 1) - 1) / 2) 计算“奇妙子序列”数量,累加得到最终结果。 核心洞察:将数字特性转化为质因数指数的数学映射,避免暴力枚举,大幅提升时间复杂度。
三、解题步骤
1. 输入与预处理:禁用流同步加速输入,读取 n。
2. 质因数分解函数 factorize(n):
1.特判 n=1 直接返回空映射。
2.优先处理质因数2(偶数情况),减少后续循环次数。
3.奇数筛法:从3开始,步长2遍历,避免重复计算偶数。
4.最终剩余质因数(若 n 为大于2的质数)单独处理。
3. 求解函数 solve(n):
1.调用 factorize 获取质因数映射。
2.遍历每个质因数 p 与指数 e,代入公式计算 k 并累加。
4. 输出结果:直接输出 solve(n) 值。
四、代码与注释
#include <iostream> #include <unordered_map> #include <cmath> using namespace std; // 质因数分解函数 unordered_map<int, int> factorize(long long n) { unordered_map<int, int> factors; if (n == 1) return factors; // 特判1(无质因数) while (n % 2 == 0) factors[2]++, n /= 2; // 优先处理质因数2 for (int i = 3; i <= sqrt(n); i += 2) { // 仅遍历奇数质因数 while (n % i == 0) factors[i]++, n /= i; } if (n > 2) factors[n]++; // 剩余质因数(若n为质数) return factors; } int solve(long long n) { if (n == 1) return 0; auto factors = factorize(n); int res = 0; for (auto [p, e] : factors) { int k = floor((sqrt(8 * e + 1) - 1) / 2); // 核心公式计算奇妙序列数 res += k; } return res; } int main() { ios::sync_with_stdio(false); cin.tie(nullptr); long long n; cin >> n; cout << solve(n); return 0; }
五、总结
本文通过解析GESP五级「奇妙数字」题目与用户代码,揭示了算法竞赛中“数学建模+高效实现”的重要性。代码巧妙结合质因数分解与推导公式,在时间复杂度与代码简洁性上达到平衡。学习此类题目可培养将数学思维融入编程的能力,建议读者深入理解质因数分解优化技巧与公式推导逻辑,提升竞赛解题水平。
原创内容 转载请注明出处