1 条题解

  • 0
    @ 2026-5-5 13:48:49

    题意简述

    给定整数 nn,考虑所有满足 1a100001\le a\le 100001bmin(10000,an)1\le b\le \min(10000, a\cdot n) 的整数对 (a,b)(a,b)。定义字符串 ss 为将 nn 的十进制表示重复 aa 次。K1o0n 的“解法”会将 ss 删除末尾 bb 个字符,将剩余字符串转为整数。若剩余字符串非空且等于真正的答案 nabn\cdot a - b,则称 (a,b)(a,b) 是正确的。对给定的 nn,求所有这样的 (a,b)(a,b)

    数据范围:n100n\le 100t100t\le 100,且所有 nn 互不相同。

    关键观察

    因为 a10000a\le 10000n100n\le 100,所以 na106n\cdot a \le 10^6。正确答案 T=nabT = n\cdot a - b[0,106][0, 10^6] 之间,因此 TT 至多只有 77 位十进制数。

    ddnn 的十进制位数(1d31\le d\le 3)。字符串 ss 的长度为 L=adL = a\cdot d。删除末尾 bb 个字符后,剩下的长度 LbL-b 必须等于 TT 的位数,且这部分必须恰好是 ss 的前缀。因此 TT 必然是 nn 的无限重复串的前缀,且长度不超过 77

    推导

    len=len(T)len = \text{len}(T),即 TT 的十进制位数。必须满足:

    1. Lb=len    b=adlenL - b = len\;\Rightarrow\; b = a\cdot d - len
    2. b=naTb = n\cdot a - T

    联立两式:

    $$a\cdot d - len = n\cdot a - T \quad\Longrightarrow\quad T - len = a\,(n - d). $$

    情况一:ndn \neq d(绝大多数情况)。
    解得 a=Tlennda = \dfrac{T - len}{\,n - d\,}。要求为整数,且 1a100001\le a\le 10000。然后计算 b=naTb = n\cdot a - T,检查 1bmin(10000,na)1\le b\le \min(10000,\, n\cdot a) 即可。

    情况二:n=dn = d,仅当 n=1n = 1 时成立(一位数且数字等于位数)。此时 Tlen=0T - len = 0,故 T=lenT = lennn 的无限重复串是 "111...",唯一满足 T=lenT = len 的前缀是 T=1T=1(因为 1=11=111211\neq21113111\neq3…)。由 b=adlen=a1b = a\cdot d - len = a - 1b=aT=a1b = a - T = a - 1,可见对任意 a2a\ge 2 均成立。结合 a10000a\le 10000b10000b\le 10000,得到 a[2,10000]a\in[2,10000],对应的 b=a1b = a-1。这些全是解。

    算法流程

    1. d=len(n)d = \text{len}(n)
    2. 构造 nn 的无限重复串,长度取 77 或稍大(例如 1010)。
    3. 枚举长度 lenlen1177(或不超过 1010),取前缀字符串 pp,转为整数 TT
    4. n=1n = 1,特殊处理:若 T=1T = 1,则对于 a=210000a = 2\dots 10000,输出 (a,a1)(a, a-1)
    5. 否则,若 (Tlen)mod(nd)=0(T - len) \bmod (n - d) = 0
      • a=(Tlen)/(nd)a = (T - len) / (n - d)
      • 1a100001\le a\le 10000,计算 b=naTb = n\cdot a - T
      • 1b100001\le b\le 10000bnab\le n\cdot a,则 (a,b)(a,b) 是一个解。
    6. 收集所有解,按需输出(样例按 aa 升序)。

    时间复杂度 O(7)O(7) 每组数据,极快。

    参考代码

    #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
    上传者