1 条题解

  • 0
    @ 2026-6-19 10:30:25

    📝 题目大意

    给定一个长度为 NN2N50002\le N\le 5000)的小写字母字符串 SS。对于每个 i=1,2,,N1i=1,2,\dots,N-1,求最大的非负整数 ll,使得 l+iNl+i\le N 且对所有 1kl1\le k\le l 都有 SkSk+iS_k\neq S_{k+i}

    💡 解题思路

    1. 题目分析NN 最大为 50005000O(N2)O(N^2) 的运算量约为 1.25×1071.25\times 10^7,在 C++ 中完全可行,直接使用双循环暴力枚举即可。

    2. 算法推导

      • 外层循环枚举 ii1iN11\le i\le N-1),即偏移量。
      • 内层循环从小到大地枚举 kk1kNi1\le k\le N-i),检查 SkS_kSk+iS_{k+i} 是否相等。
      • SkSk+iS_k\neq S_{k+i},则 ll 可以增加 11(这对字符满足条件);若 Sk=Sk+iS_k=S_{k+i},则 break 跳出内层循环,因为后续更大的 kk 必然不满足条件。
      • 最终 ll 即为满足条件的最大长度,直接输出。
    3. 边界与细节

      • l=0l=0 始终满足条件,因此当 S1=S1+iS_1=S_{1+i} 时也会正确输出 00
      • 字符串下标从 00 开始,代码中 SkS_k 对应 s[k-1]Sk+iS_{k+i} 对应 s[k+i-1],注意下标偏移。
      • 内层循环上限为 nin-i,确保 l+iNl+i\le N

    ⏱️ 复杂度分析

    • 时间复杂度O(N2)O(N^2),外层循环 N1N-1 次,内层循环至多 NiN-i 次。
    • 空间复杂度O(N)O(N),仅存储输入字符串。

    💻 标准代码 (C++)

    #include <bits/stdc++.h>
    using namespace std;
    #define rep(i, n) for (int i = 0; i < (int)(n); i++)
    
    int main() {
      int n;
      string s;
      cin >> n >> s;
      
      // 枚举偏移量 i(对应题目中的 i,从 1 到 N-1)
      for(int i = 1; i < n; i++){
        int l = 0;  // 最大满足条件的长度
        // 从小到大枚举 k,检查 S[k] 与 S[k+i] 是否不同
        for(int k = 1; k <= n-i; k++){
          // 注意:题目中下标从 1 开始,代码中从 0 开始
          if(s.at(k-1) == s.at(k+i-1)) break; // 一旦相等,此后的 k 都不满足
          l++;  // 当前 k 满足条件,l 加 1
        }
        cout << l << endl;
      }
    }
    
    • 1

    信息

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