1 条题解
-
0
📝 题目大意
给定整数 ,判断是否存在正整数 使得 。若存在输出任意一组 ,否则输出 。
💡 解题思路
-
题目分析: 上限为 ,而 和 均是指数增长,因此 和 的取值上限非常小。具体地,,,所以 、。这意味着我们可以暴力枚举其中一个变量,再用哈希表快速查询另一个变量是否存在。
-
算法推导:
- 首先预处理出所有不超过 的 的幂 (),将它们存入哈希表
mp,键为 的值,值为对应的指数 。 - 然后枚举 (),计算 ,并检查 是否在哈希表中。若存在,则找到一组解 ,直接输出并结束程序。
- 这本质上是"枚举一个维度 + 哈希表查另一个维度"的双指针/预处理优化思路,将 的双重循环降为 。
- 代码中
mp存储5^B → B的映射,while (mul * 5 <= n)循环逐次生成 ;同理,第二个while (mul * 3 <= n)枚举 ,每次用mp.count(n - mul)判断差值是否为 的幂。
- 首先预处理出所有不超过 的 的幂 (),将它们存入哈希表
-
边界与细节:
- 和 均为正整数(),因此代码中
cnt初始为 ,先cnt++再mul *= 3/5,确保从 、 开始枚举。 - 当 较小时(如 ),两个
while循环均不会进入,mp为空,程序直接输出 ,这是正确的。 - 使用
long long避免中间计算溢出, 和 均在long long范围内。
- 和 均为正整数(),因此代码中
⏱️ 复杂度分析
- 时间复杂度:预处理 的幂需要 次迭代,枚举 的幂需要 次迭代,每次哈希表查询为 。总时间复杂度为 。
- 空间复杂度:哈希表
mp存储最多 个键值对,空间复杂度为 。
💻 标准代码 (C++)
#include <bits/stdc++.h> using namespace std; using LL = long long; LL n; // mp: 存储 5^B -> B 的映射 map<LL, int> mp; int main(){ cin >> n; // 预处理所有不超过 n 的 5 的幂 int cnt = 0; LL mul = 1; while (mul * 5 <= n){ cnt++; // B 从 1 开始 mul *= 5; // mul = 5^cnt mp[mul] = cnt; // 记录 5^cnt 对应的指数 } // 枚举 3^A,检查 n - 3^A 是否为 5 的幂 mul = 1, cnt = 0; while (mul * 3 <= n){ cnt++; // A 从 1 开始 mul *= 3; // mul = 3^cnt if (mp.count(n - mul)){ // 差值 n - 3^A 是 5 的某次幂 cout << cnt << ' ' << mp[n - mul] << '\n'; return 0; } } // 无解 cout << "-1\n"; return 0; } -
- 1
信息
- ID
- 855
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- (无)
- 递交数
- 1
- 已通过
- 1
- 上传者