zoukankan      html  css  js  c++  java
  • hdu 3613 (KMP)回文串

    将模板串s倒置,并尾加到原串后,求得next[]数组,根据next[]数组的性质,便可得前缀的回文串,

    同理交原串尾加到倒置串后,便可求得后缀的回文串,然后前缀串和后缀串分开,遍历即可求得最大值!

     1 #include <iostream>
     2 #include <cstring>
     3 #include <cstdio>
     4 #include <algorithm>
     5 using namespace std;
     6 #define N 1000010
     7 int v[26], rsum[N/2], lsum[N/2], sum1[N/2], sum2[N/2], next[N];
     8 char s[N/2], s1[N], s2[N];
     9 
    10 void getfail(char* s, int len){   //next[]数组
    11     next[0] = 0; next[1] = 0;
    12     for(int i = 1; i < len; ++i){
    13         int j = next[i];
    14         while(j && s[j] != s[i]) j = next[j];
    15         next[i+1] = s[i] == s[j] ? j + 1 : 0;
    16     }
    17 }
    18 
    19 int main()
    20 {
    21     int t, i;
    22     scanf("%d",&t);
    23     while(t--){
    24         for(i = 0; i < 26; ++i) scanf("%d", &v[i]);
    25         scanf("%s", s);
    26         int len = strlen(s);
    27         sum1[0] = v[s[0]-'a'];
    28         for(i = 1; i < len; ++i){
    29             sum1[i] = sum1[i-1] + v[s[i]-'a'];
    30         }
    31         strcpy(s1, s);
    32         reverse(s1, s1+len);
    33         sum2[0] = v[s1[0]-'a'];
    34         for(i = 1; i < len; ++i)
    35             sum2[i] = sum2[i-1] + v[s1[i]-'a'];
    36         strcpy(s1, s); s1[len] = '!';   //前缀
    37         strcpy(s1+len+1, s);
    38         reverse(s1+len+1, s1+len+len+1);
    39        // cout<<s1<<endl;
    40         strcpy(s2, s); s2[len] = '!';   //后缀
    41         strcpy(s2+len+1, s);
    42         reverse(s2, s2+len);      //倒置字符串
    43        // cout<<s2<<endl;
    44         memset(rsum, 0, sizeof(rsum));
    45         memset(lsum, 0, sizeof(lsum));
    46         getfail(s1, strlen(s1));
    47         i = strlen(s1);
    48         do{
    49             i = next[i];
    50             rsum[i] = sum1[i-1];  //前缀成回文串的价值和
    51         }while(next[i]);
    52 
    53         getfail(s2, strlen(s2));
    54 
    55         i = strlen(s2);
    56         do{
    57             i = next[i];
    58             lsum[i] = sum2[i-1];  //后缀成回文串的价值和
    59         }while(next[i]);
    60         int ans = -(1<<30);
    61         for(i = 1; i < len; ++i)
    62             ans = max(ans, rsum[i] + lsum[len-i]);  //遍历求最大值
    63         printf("%d
    ",ans);
    64     }
    65     return 0;
    66 }
    View Code
  • 相关阅读:
    矩阵分析及其在线性代数中的应用(3-4)
    矩阵分析及其在线性代数中的应用(1-2)
    信息检索的评价标准
    Converting Between Image Classes (matlab 中图像类之间的转换)
    Ubuntu 14.04,root the Nexus 7 (2013).
    ACM进阶计划
    matlab R2012a in ubuntu12.04
    人,绩效和职业道德
    运行及总结
    仓库管理 测试计划
  • 原文地址:https://www.cnblogs.com/yaling/p/3221350.html
Copyright © 2011-2022 走看看