3 条题解

  • 5
    @ 2023-8-19 0:13:41

           \ \ \ \ \ \ \ 动态规划。

           \ \ \ \ \ \ \

    isPalindromic[i][j]{\rm isPalindromic}[i][j]

    记录从位置jj开始长度为ii的子串是否是回文串。即位置jj到位置j+i1j+i-1的子串是否是回文串。

           \ \ \ \ \ \ \ 考虑到“位置jj到位置j+i1j+i-1的子串”=“位置jj的字符”+“位置j+1j+1到位置j+i2j+i-2的子串”+“位置j+i1j+i-1的字符”;则判断从位置jj开始长度为ii的子串是否是回文串,只需要判断从位置j+1j+1开始长度为i2i-2的子串是否是回文串,以及位置jj的字符是否等于位置j+i1j+i-1的字符,即:

    if((s[j] == s[j + i - 1]) && (isPalindromic[i - 2][j + 1]))
        isPalindromic[i][j] = true;
    

           \ \ \ \ \ \ \ 同时我们需要边界条件:从任意位置开始长度为00的子串和长度为11的子串都认为是回文串,它们分别成为偶数长回文串和奇数长回文串的边界条件,即:

    for(int i = 0; i <= len; i++){
        isPalindromic[0][i] = true;
        isPalindromic[1][i] = true;
    }
    

           \ \ \ \ \ \ \ 并且,小心题目挖的坑:字符串中可能有空格,因此我们直接getline{\rm getline}读入,不要用cin{\rm cin},它会只读入空格前面的部分。

    cin.getline(s, 1300);
    

           \ \ \ \ \ \ \ 最终,我们令长度ii22到字符串总长度搜索并输出结果,就能够使得回文子串按照长度顺序排列;在对ii的循环内,令位置jj从左到右搜索,就能够使得同样长度的回文子串按先后出现的顺序输出。

           \ \ \ \ \ \ \ 完整代码如下:

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    using namespace std;
    
    bool isPalindromic[1300][1300];
    
    int main(){
        char s[1300];
        cin.getline(s, 1300);
        int len = strlen(s);
        for(int i = 0; i <= len; i++){
            isPalindromic[0][i] = true;
            isPalindromic[1][i] = true;
        }
        for(int i = 2; i <= len; i++){
            for(int j = 0; j <= len - i; j++){
                if((s[j] == s[j + i - 1]) && (isPalindromic[i - 2][j + 1])){
                    isPalindromic[i][j] = true;
                    for(int k = 0; k <= i - 1; k++){
                        cout << s[j + k];
                    }
                    cout << endl;
                }
            }
        }
        return 0;
    }
    
    • @ 2025-1-16 19:31:52

      大佬的动态规划,让我打开了新的思路,膜拜

    • @ 2025-1-16 19:54:01

      区间dp👍 👍

  • 0
    @ 2025-1-22 16:09:34
    #include<iostream>
    #include<cstring>
    #include<algorithm>
    const int N = 1210;
    char f[N];
    using namespace std;
    
    // 判断字符串 s 从 start 到 end 是否为回文串
    bool isPalindrome(char s[], int start, int end) {
        while (start < end) {
            if (s[start]!= s[end]) {
                return false;
            }
            start++;
            end--;
        }
        return true;
    }
    
    int main() {
        cin.getline(f, N);
        int q = strlen(f);
        for (int len = 2; len <= q; len++) {  // 枚举子串的长度
            for (int start = 0; start + len - 1 < q; start++) {  // 枚举子串的起始位置
                int end = start + len - 1;
                if (isPalindrome(f, start, end)) {  // 判断是否为回文串
                    for (int i = start; i <= end; i++) {
                        cout << f[i];
                    }
                    cout << endl;
                }
            }
        }
        return 0;
    }
    滑动窗口算法
    
    • 0
      @ 2024-12-26 16:09:08
      #include <iostream>
      #include <string>
      int main() {
        using namespace std;
        string a, b;
        int x = 1;
        getline(cin, a);
        for (int i = 2; i <= a.size(); i++)
          for (int j = 0; j < a.size() - i + 1; j++, x = 1) {
            b = a.substr(j, i);
            for (int k = 0; k < i / 2; k++)
              if (b[k] != b[i - 1 - k]) x = 0;
            if (x == 1) cout << b << endl;
          }
      }
      
      • 1

      信息

      ID
      52
      时间
      1000ms
      内存
      256MiB
      难度
      8
      标签
      递交数
      1050
      已通过
      156
      上传者