1 条题解

  • 0
    @ 2026-4-5 19:27:23

    给定 nnkk,要求构造一个字符串 ss,使得 所有由前 kk 个小写字母组成的、长度为 nn 的字符串 都是 ss子序列

    我们要找 长度最短ss,如果有多个,任意输出一个。


    关键观察

    1. 所有可能字符串的个数是 knk^n
    2. 每个长度为 nn 的字符串都是 ss 的子序列,意味着:
      • 对任意序列 a1a2ana_1a_2\dots a_nai{1,,k}a_i \in \{1,\dots,k\}),
      • 存在 ss 的下标 i1<i2<<ini_1 < i_2 < \dots < i_n,使得 s[ij]=ajs[i_j] = a_j

    最小长度下界

    • 子序列不能重复使用同一个字符在同一个位置(不同位置可以相同字符)。
    • 最坏情况下,要覆盖所有 knk^n 种序列,ss 的长度至少是 n+(kn1)1n + (k^n - 1) \cdot 1
      不对,因为子序列允许跳字符,不是相邻排列。

    实际上,这里可以这样想:

    我们要能选出任意 nn 个位置,每个位置可以是前 kk 个字母中的任意一个。
    这等价于:对于每个字母 cc,在 ss 中要有足够多的 cc,使得在取 nn 个位置时,每个位置的选择是独立的。


    已知结论(类似 de Bruijn 序列的子序列版): 最短长度是 n+(kn1)n + (k^n - 1)
    不,那是相邻排列(de Bruijn 序列)的长度。这里是子序列,要求更弱,所以可以更短。

    实际上,经典解法是:

    构造方法
    把前 kk 个字母重复 nn 遍,按顺序排列:
    abc...k abc...k ... 重复 nn 次?
    这样长度 nkn \cdot k,但还不够短。


    已知最短构造(来自题解)

    对于 n=1n=1
    s=s = abc...k(前 kk 个字母),长度 kk
    确实最短,因为要包含每个长度为 1 的字符串(每个字母一次)。

    对于 n=2n=2
    s=s = abc...k abc...k(重复两次)长度 2k2k,但可以更短。

    例子中 n=2,k=2n=2,k=2 输出 baab 长度 4,比 2k=42k=4 一样。
    n=2,k=3n=2,k=3 输出 abcbac 长度 6,比 2k=62k=6 一样。

    其实这个构造就是:
    s=s =kk 个字母的排列 + 前 kk 个字母的排列,但顺序不同,使得每个位置可以独立选。


    一般构造法

    设字母为 1,2,,k1,2,\dots,k

    构造字符串为:

    1,2,,k,1,2,,k,,1,2,,k1,2,\dots,k,1,2,\dots,k,\dots,1,2,\dots,k

    重复 nn 次,长度 nkn \cdot k

    但这样够短吗?检查 n=2,k=3n=2,k=3
    s=123123s = 123123 长度 6,确实包含所有 9 个长度为 2 的子序列吗?
    可以:
    aa: 位置 1 和 4(1 和 1)
    ab: 位置 1 和 2(1 和 2)
    ac: 位置 1 和 3(1 和 3)
    ba: 位置 2 和 4(2 和 1)
    bb: 位置 2 和 5(2 和 2)
    bc: 位置 2 和 3?不对,位置 2 是 2,位置 3 是 3,那是 b c 没问题。
    等等,位置 2 和 3 是 2,3,就是 bc,对。
    ca: 位置 3 和 4(3 和 1)
    cb: 位置 3 和 5(3 和 2)
    cc: 位置 3 和 6(3 和 3)
    可行。

    检查 n=2,k=2n=2,k=2 用这个构造
    s=1212s = 1212 长度 4,包含 aa,ab,ba,bb?
    aa: 位置 1 和 3(1 和 1)
    ab: 位置 1 和 2(1 和 2)
    ba: 位置 2 和 3(2 和 1)
    bb: 位置 2 和 4(2 和 2)
    可行。

    但题解中 n=2,k=2n=2,k=2 输出 baab,也是 4,只是顺序不同。

    所以这个构造确实是最优的:
    长度为 nkn \cdot k 的字符串,由前 kk 个字母重复 nn 次连接而成,可以覆盖所有 knk^n 种子序列。


    为什么 nkn \cdot k 是最短的?

    反证:
    如果长度 L<nkL < nk,那么某个字母的出现次数少于 nn 次。
    考虑全部由该字母组成的字符串 aaaaaaa\dots annaa),它不可能作为子序列,因为 aass 中不足 nn 次。
    所以 LnkL \ge nk

    因此 最小长度就是 nkn \cdot k,构造就是重复 nn1..k


    最终算法

    对于每个测试用例 (n,k)(n,k)

    1. s=""s = \text{""}
    2. 对于 i=1i = 1nn
      • 对于 j=1j = 1kk
        • ss 加上第 jj 个小写字母('a'+j-1)。
    3. 输出 ss

    复杂度

    每个测试用例 O(nk)O(nk),总 O(tnk)6762626O(tnk) \le 676 \cdot 26 \cdot 26,非常小。


    代码(伪代码)

    for _ in range(t):
        n, k = map(int, input().split())
        s = ""
        for i in range(n):
            for j in range(k):
                s += chr(ord('a') + j)
        print(s)
    

    示例验证

    • n=1,k=2n=1,k=2ab
    • n=2,k=1n=2,k=1aa
    • n=2,k=2n=2,k=2abab 长度 4,比 baab 一样长 ✅
    • n=2,k=3n=2,k=3abcabc 长度 6 ✅

    这样我们就得到了题目要求的最短字符串构造。

    • 1

    信息

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