5 条题解

  • 6
    @ 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-12-3 16:33:27

    直接暴力枚举解决也可

    #include<iostream>
    #include<string>
    #include<cstring>
    #define N 1200
    using namespace std;
    bool slove(const char s[]){
    char rs[N]; //构造相反字符串
    int n = strlen(s); // 求出字符串长度
    for(int i=n-1;i>=0;i--){
    rs[i]=s[n-i-1];
    }
    rs[n]='\0';
    if(strcmp(s,rs) == 0)
    return true;
    else
    return false;
    }
    int main(){
    string str;
    getline(cin,str);
    for(int i=2;i<=str.size();i++){ //字符串长度
    for(int j=0;j<=str.size()-i;j++){//从第几个开始截取
    //从第j开始截取,截取i个
    string ss = str.substr(j,i);
    if(slove(ss.c_str())){
    cout<<ss<<endl;
    }
    }
    }
    

    }

    
    
    • 0
      @ 2025-11-27 17:05:26
      #include<stdio.h>
      #include<string.h>
      int main()
      {
          char s[1201];
          fgets(s,1201,stdin);//用scanf不符题意
          int n=strlen(s);
          for(int k=2;k<=n;k++)
          {
              for(int r=0;r<n;r++)//r窗口右边界
              {
                  int flag=0;
                  if(r<k-1)
                  {
                      continue;
                  }
                  int i=r;
                  for(int l=r-k+1;l<r-k+1+k/2;l++)//l窗口左边界
                  {
                      if(s[l]!=s[i--])
                      {
                         flag=1;
                         break;
                      }
                  }
                  if(flag)
                  {
                      continue;
                  }
                  for(int l=r-k+1;l<=r;l++)
                  {
                      printf("%c",s[l]);
                  }
                  printf("\n");
              }
          }
          return 0;
      }
      
      • -1
        @ 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;
        }
        滑动窗口算法
        
        • -1
          @ 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
          标签
          递交数
          1390
          已通过
          201
          上传者