1 条题解

  • 0
    @ 2025-10-16 14:22:56

    题解说明

    问题背景:
    这段程序实现了一个“递归生成 + 压缩表示”的字符串构造器。输入一个整数 nn,程序会按照固定的递归规则生成一个核心字符串,再在末尾拼接 nn 个字符 'E'nn 个字符 'C'。为了避免输出过长的重复串,程序在构造时会使用「数字+串」或「数字+[串]」的压缩格式。

    核心函数解析:

    1.1. repeat(s,k):

    • 功能:生成字符串 ss 重复 kk 次的压缩表示。
    • 规则:
      • k=0k=0ss 为空串 → 返回空串。
      • k=1k=1 → 返回 ss
      • 2k92 \le k \le 9 → 返回 k + sk + [s](若 ss 长度大于 11,加方括号避免歧义)。
      • k>9k > 9 → 将 kk 拆分为 9×(k/9)+(kmod9)9 \times (k/9) + (k \bmod 9),递归构造,避免出现大于 99 的数字。

    例子:

    • repeat("A",3)"3A"
    • repeat("AB",2)"2[AB]"
    • repeat("X",20)"9[2X]2X"

    2.2. getres(n):

    • 功能:递归生成核心字符串。
    • 递归基:
      • n=1n=1"A"
      • n=2n=2"AEACA"
    • 递归步骤:
      • m=(n1)/2m=(n-1)/2,先递归得到 getres(m)getres(m)
      • 拼接以下部分:
        1. getres(m)getres(m) 重复 22
        2. mm'E'
        3. mm'C'
        4. (m\big(m'E' + (m1)(m-1)"AC" + `"A"\big)重复 重复 m$ 次
        5. mm'E'
        6. 2m2m"AC"
        7. 一个 'A'
      • nn 为偶数(即 2m+1<n2m+1<n),再追加:
        • (2m+1)(2m+1)'E'
        • (2m+1)(2m+1)"AC"
        • 一个 'A'

    3.3. 主函数 main:

    • 默认生成一个随机 nn(范围 [1017,1018][10^{17},10^{18}]),但会被用户输入覆盖。
    • 调用 getres(n) 得到核心串,再拼接 nn'E'nn'C'
    • 输出最终结果。

    复杂度分析:

    • 递归深度约为 O(logn)O(\log n)
    • 每层拼接涉及 O(m)O(m) 的重复构造,但由于使用了压缩表示,输出长度远小于真实展开串。
    • 整体复杂度主要取决于递归与字符串拼接,适合大规模 nn
    #include <bits/stdc++.h>
    using namespace std;
    
    // 类型别名:简化长类型书写,提升代码可读性
    typedef long long ll;               // 将long long简写为ll,适配大数值计算
    typedef pair<int, int> pii;         // 定义键值对类型(本代码暂未实际使用,预留扩展)
    
    /**
     * 字符串重复生成函数(带格式优化)
     * 功能:根据重复次数k和基础字符串s,生成简洁格式的重复字符串
     * @param s 待重复的基础字符串
     * @param k 重复次数(非负整数)
     * @return 按规则生成的重复字符串
     */
    string repeat(const string &s, ll k) {
        // 特殊情况1:重复次数为0或基础串为空,直接返回空串
        if (k == 0 || !s.size())
            return "";
    
        // 特殊情况2:重复1次,无需格式优化,直接返回原串
        if (k == 1)
            return s;
    
        // 情况3:重复次数≤9,用「数字+串」或「数字+[串]」简化格式
        // 例:k=3、s="A"→"3A";k=2、s="AB"→"2[AB]"(避免歧义)
        if (k <= 9) {
            return string(1, k + '0') + (s.size() == 1 ? s : "[" + s + "]");
        }
    
        // 情况4:重复次数>9,递归拆分为「9倍重复 + 余数重复」
        // 例:k=20→拆为9*2 + 2→先生成"9[2s]",再拼接"2s",避免数字过长
        return repeat(repeat(s, k / 9), 9) + repeat(s, k % 9);
    }
    
    /**
     * 递归生成核心字符串函数
     * 功能:根据参数n,按固定规则递归生成特定格式的核心字符串
     * @param n 控制生成规模的参数(正整数)
     * @return 符合规则的核心字符串
     */
    string getres(ll n) {
        // 递归终止条件1:n=1时,返回固定基础串"A"
        if (n == 1) {
            return "A";
        }
    
        // 递归终止条件2:n=2时,返回固定基础串"AEACA"
        if (n == 2) {
            return "AEACA";
        }
    
        // 递归递推:计算中间参数m = (n-1)/2(整数除法,适配n奇/偶)
        ll m = (n - 1) / 2;
        // 递归获取m对应的核心串,作为当前层拼接的基础
        string s = getres(m);
    
        // 核心拼接逻辑:按固定顺序组合多段重复字符串
        s = repeat(s, 2)                  // 第1段:基础串s重复2次
            + repeat("E", m)              // 第2段:m个字符'E'
            + repeat("C", m)              // 第3段:m个字符'C'
            // 第4段:(m个'E' + (m-1)个"AC" + 1个"A") 整体重复m次
            + repeat(repeat("E", m) + repeat("AC", m - 1) + "A", m)
            + repeat("E", m)              // 第5段:m个字符'E'
            + repeat("AC", 2 * m)         // 第6段:2*m个"AC"
            + "A";                        // 第7段:1个字符'A'
    
        // 补全逻辑:若n为偶数(2*m+1 < n),追加额外段落保证规则统一
        if (2 * m + 1 < n) {
            s = s
                + repeat("E", 2 * m + 1)  // 追加段1:(2*m+1)个字符'E'
                + repeat("AC", 2 * m + 1) // 追加段2:(2*m+1)个"AC"
                + "A";                    // 追加段3:1个字符'A'
        }
    
        return s;
    }
    
    // 随机数生成器初始化(用于测试时生成超大n,实际运行以用户输入为准)
    mt19937_64 gen((unsigned long long)new char ^ time(0));  // 高质量64位随机数引擎
    uniform_int_distribution<ll> rnd(1e17, 1e18);            // 随机数范围:[1e17, 1e18]
    
    int main(void) {
        // 步骤1:生成测试用随机n(后续会被用户输入覆盖,仅作默认值)
        ll n = rnd(gen);
        // 步骤2:读取用户输入的n(优先级高于随机n,以用户需求为准)
        scanf("%lld", &n);
    
        // 步骤3:生成最终字符串=核心串 + n个'E' + n个'C'
        string s = getres(n) + repeat("E", n) + repeat("C", n);
    
        // 步骤4:输出最终结果
        cout << s << endl;
        return 0;
    }
    
    • 1

    信息

    ID
    3178
    时间
    1000ms
    内存
    256MiB
    难度
    10
    标签
    递交数
    2
    已通过
    1
    上传者