• YBT132 回文子串


    传送门:YBT132 回文子串

    样例输入

    abcbabcbabcba
    abacacbaaaab
    END

    样例输出

    Case 1: 13 
    Case 2: 6


    题解

      该题解面向新手

      首先我们可以发现一个字符串的hash值和倒过来的hash值相等(也就是倒过来是同一个字符串), 那么他是回文的。

      那么现在问题来了,我们怎么找到最大的回文子串呢? 根据题目和数据范围容易发现使用二分答案。

      也就是说,二分最大长度,O(n)枚举是否存在(通过hash预处理)

      大概的思路有了, 但众所周知回文字符串分为奇串和偶串,也就是说不存长度为5的回文串时,可能还存在长度为6的。

      比如aaabaaa, 不存在长度为6,4的子串。读者仔细思考发现,答案不单调无法二分。

      但你想,事实上奇数和偶数长度分别都是单调的: 不存在长度为5的子串,就一定不存在长度为7, 9, 11、、、的子串回文, 偶数易燃。

      这就有很多处理方法了, 比如manache什么的, 不过这里讲一种麻烦但新手容易想到的方法

        奇偶串分别二分

      有点累,可以看看代码细节....

      宁还是别看了, 多组数据不清空....陆陆续续调了个好几天,实在看不了,抱歉,太累了没法改了

      

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <string.h>
     4 #define ull unsigned long long
     5 using namespace std;
     6 
     7 const int N = 2000005;
     8 const ull b=231, p=233371;
     9 char s[N];
    10 int len, T=0;
    11 ull hash1[N], hash2[N], c[N];
    12 
    13 ull getHash1(int l, int r){
    14     if(l == 0) return hash1[r];
    15     return ((hash1[r] - hash1[l-1]*c[r-l+1]) );
    16 }
    17 
    18 ull getHash2(int l, int r){
    19     if(r == N) return hash2[r];
    20     return ((hash2[l] - hash2[r+1]*c[r-l+1]) );
    21 }
    22 
    23 int main(){
    24     c[0]=1;
    25     for(int i=1; i<N; i++) c[i] = (c[i-1]*b); 
    26     while(++T){
    27         for(int i=0; i<N; i++) s[i]=0, hash1[i] = hash2[i] = 0;
    28         cin >> s;
    29         if(!strcmp(s, "END")) return 0;
    30         
    31         len=strlen(s), hash1[0]=s[0], hash2[len-1]=s[len-1];
    32         
    33         for(int i=1; i<len; i++) hash1[i] = (hash1[i-1]*b + (ull)s[i]);
    34         for(int i=len-2; i>=0; i--) hash2[i] = (hash2[i+1]*b + (ull)s[i]);
    35         
    36         int ans = 1, l=1, r=len;
    37         while(l<r){
    38             int mid = (l+r)/2, flag=1;
    39             if(mid%2) mid++;
    40             for(int i=0; i+mid-1<len; i++){
    41                 if(getHash1(i, i+mid-1) == getHash2(i, i+mid-1)){
    42                     flag=0;
    43                     ans = mid;
    44                     l = mid + 1;    
    45                     break;                
    46                 }
    47             }
    48             
    49             if(flag) r = mid - 1;
    50         }
    51         
    52         l=1, r=len;
    53         while(l<r){
    54             int mid = (l+r)/2, flag=1;
    55             if((mid%2)==0) mid++;
    56             for(int i=0; i+mid-1<len; i++){
    57                 if(getHash1(i, i+mid-1) == getHash2(i, i+mid-1)){
    58                     flag=0;
    59                     ans = max(mid, ans);
    60                     l = mid + 1;    
    61                     break;                
    62                 }
    63             }
    64             
    65             if(flag) r = mid - 1;
    66         }
    67         
    68         cout << "Case " << T << ": " << ans << endl;
    69         
    70     } 
    71 }

      

     
  • 相关阅读:
    Json.Net学习笔记(八) 序列化的回调方法
    PowerDesigner 使用的一些技巧(转)
    Json.Net学习笔记(十三) 缩小序列化Json的大小
    Json.Net学习笔记(十四) JSON的部分序列化
    MSDTC服务配置 今天碰到的情况
    Json.Net学习笔记(十一) CustomCreationConverter
    让工作自动化
    Json.Net学习笔记(十二) 协议解析
    Json.Net学习笔记(九) 异常处理
    通过PB认证
  • 原文地址:https://www.cnblogs.com/ltdjcoder/p/14559432.html
Copyright © 2020-2023  润新知