1 条题解
-
0
题意简述
给定整数 ,考虑所有满足 , 的整数对 。定义字符串 为将 的十进制表示重复 次。K1o0n 的“解法”会将 删除末尾 个字符,将剩余字符串转为整数。若剩余字符串非空且等于真正的答案 ,则称 是正确的。对给定的 ,求所有这样的 。
数据范围:,,且所有 互不相同。
关键观察
因为 ,,所以 。正确答案 在 之间,因此 至多只有 位十进制数。
设 为 的十进制位数()。字符串 的长度为 。删除末尾 个字符后,剩下的长度 必须等于 的位数,且这部分必须恰好是 的前缀。因此 必然是 的无限重复串的前缀,且长度不超过 。
推导
设 ,即 的十进制位数。必须满足:
- ;
- 。
联立两式:
$$a\cdot d - len = n\cdot a - T \quad\Longrightarrow\quad T - len = a\,(n - d). $$情况一:(绝大多数情况)。
解得 。要求为整数,且 。然后计算 ,检查 即可。情况二:,仅当 时成立(一位数且数字等于位数)。此时 ,故 。 的无限重复串是
"111...",唯一满足 的前缀是 (因为 ,,…)。由 及 ,可见对任意 均成立。结合 和 ,得到 ,对应的 。这些全是解。算法流程
- 令 。
- 构造 的无限重复串,长度取 或稍大(例如 )。
- 枚举长度 从 到 (或不超过 ),取前缀字符串 ,转为整数 。
- 若 ,特殊处理:若 ,则对于 ,输出 。
- 否则,若 :
- ;
- 若 ,计算 ;
- 若 且 ,则 是一个解。
- 收集所有解,按需输出(样例按 升序)。
时间复杂度 每组数据,极快。
参考代码
#include <bits/stdc++.h> using namespace std; void solve() { int n; cin >> n; string ns = to_string(n); int d = ns.size(); // 生成足够长的重复串 string repeated; for (int i = 0; i < 10; ++i) repeated += ns; vector<pair<int,int>> ans; if (n == 1) { // n=1 时, T=1 固定,a 从 2 到 10000 for (int a = 2; a <= 10000; ++a) { int b = a - 1; if (b <= 10000) ans.push_back({a, b}); } } else { for (int len = 1; len <= 7; ++len) { string pref = repeated.substr(0, len); int T = stoll(pref); if (T < len) continue; // 避免除零或负,但实际不会 int num = T - len; int den = n - d; if (num % den) continue; int a = num / den; if (a < 1 || a > 10000) continue; int b = n * a - T; if (b < 1 || b > 10000 || b > n * a) continue; ans.push_back({a, b}); } } // 排序输出(可选) sort(ans.begin(), ans.end()); cout << ans.size() << "\n"; for (auto [a, b] : ans) { cout << a << " " << b << "\n"; } } int main() { ios::sync_with_stdio(false); cin.tie(nullptr); int t; cin >> t; while (t--) solve(); return 0; }
- 1
信息
- ID
- 6896
- 时间
- 3000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- 递交数
- 1
- 已通过
- 1
- 上传者