1 条题解
-
0
题目详解
给定一个奇数 ,需要构造 个不同的 位整数(无前导零),每个整数都是完全平方数,且所有数的 数字多重集 相同。
关键观察
- 如果 是平方数,则 也是平方数,且长度增加 。
- 特殊的平方数形如 $(3 \cdot 10^{k+1} + 1)^2 = 9\underbrace{0\dots0}_{k}6\underbrace{0\dots0}_{k}1$
和 $(10^{k+1} + 3)^2 = 1\underbrace{0\dots0}_{k}6\underbrace{0\dots0}_{k}9$,其中 。 - 这些数的数字多重集都包含一个 、一个 、一个 和 个 。
构造方法(递推)
基础情况:
- :(即 )
- :,,
递推步骤:
对任意奇数 ,令 (整数)。- 对 的所有解,在每个数后面添加两个 0,得到 个长度为 的平方数。
- 再添加两个新数:
- $A = 9\underbrace{0\dots0}_{k}6\underbrace{0\dots0}_{k}1$
(即 ) - $B = 1\underbrace{0\dots0}_{k}6\underbrace{0\dots0}_{k}9$
(即 )
- $A = 9\underbrace{0\dots0}_{k}6\underbrace{0\dots0}_{k}1$
这样总共得到 个不同的 位平方数,且它们的数字多重集相同(都包含一个 、一个 、一个 和 个 )。
正确性验证
- 长度: 和 的位数恰好为 。
- 无前导零:最高位分别为 和 ,满足条件。
- 平方性:由展开式可得:$$(3 \cdot 10^{k+1} + 1)^2 = 9 \cdot 10^{2k+2} + 6 \cdot 10^{k+1} + 1 $$对应数字序列 , 个 ,, 个 ,。$$(10^{k+1} + 3)^2 = 10^{2k+2} + 6 \cdot 10^{k+1} + 9 $$对应数字序列 , 个 ,, 个 ,。
- 多重集相同:所有数均由 各一个和 个 组成(因为 位,除去三个非零数字,剩下 个零)。
算法实现
按上述递推预计算所有 的解,然后对每个测试用例直接输出。
#include <iostream> #include <vector> #include <string> using namespace std; const int MAX_N = 99; vector<vector<string>> precompute() { vector<vector<string>> sol(MAX_N + 1); // 基础情况 sol[1] = {"1"}; sol[3] = {"169", "196", "961"}; // 递推构造 n = 5, 7, 9, ..., 99 for (int n = 5; n <= MAX_N; n += 2) { int k = (n - 3) / 2; // 中间零的个数 string s1 = "9" + string(k, '0') + "6" + string(k, '0') + "1"; string s2 = "1" + string(k, '0') + "6" + string(k, '0') + "9"; // 从 n-2 的解添加 "00" 得到新解 for (const string& x : sol[n-2]) { sol[n].push_back(x + "00"); } sol[n].push_back(s1); sol[n].push_back(s2); } return sol; } int main() { auto solutions = precompute(); int t; cin >> t; while (t--) { int n; cin >> n; for (const string& s : solutions[n]) { cout << s << "\n"; } } return 0; }复杂度
- 预处理时间 ,满足 总和限制。
- 每个测试回答时间 。
- 1
信息
- ID
- 6495
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 6
- 标签
- 递交数
- 1
- 已通过
- 1
- 上传者