zoukankan      html  css  js  c++  java
  • ural 1297. Palindrome

    题目链接:http://acm.timus.ru/problem.aspx?space=1&num=1297

    求最长回文子串

    典型的后缀数组的入门题目,但是可以用更简单的方法解决,毕竟数据量比较小啊

    转载:

    题目大意:给出一个字符串,求它的连续最长回文子串。

    分析:这题数据规模不大(n<=1000),所以直接暴力可以解决。不过如果数据规模大了,暴力就不行了。这里介绍后缀数组的做法。

    首先,枚举回文子串的中心所在位置。这里要分回文串长度为奇数和偶数两种情况考虑。这两个问题均可以转化为求一个后缀和一个倒着写的后缀的最长公共前缀。

    具体地,将原串与反着写之后的原串相连,中间以一个特殊字符隔开。这个特殊字符只要不是0号,不影响后缀的排序,就没有问题。(不能是0是因为我的倍增算法要求除了字符串的最后一位以外,其它位不能为0,否则会出错)然后算出height数组。两个后缀的最长公共前缀为两个后缀排序之后,它们之间的串的height值的最小值。这个可以自己举个具体例子好好体会。用st算法求解rmq问题即可。

    ********************************************************************************************************************************************************************************************************************

    代码如下:

     1 #include<iostream>
     2 #include<cstring>
     3 #include<cmath>
     4 using namespace std;
     5 const int maxn=2010;
     6 int n,w[maxn],wa[maxn],wb[maxn],wv[maxn];
     7 int a[maxn],sa[maxn],rank[maxn],height[maxn],f[maxn][20];
     8 int cmp(int *r,int a,int b,int l){
     9     return r[a]==r[b]&&r[a+l]==r[b+l];
    10 }
    11 void da(int *r,int *sa,int n,int m){
    12     int i,j,p,*x=wa,*y=wb,*t;
    13     for (i=0;i<m;i++) w[i]=0;
    14     for (i=0;i<n;i++) w[x[i]=r[i]]++;
    15     for (i=1;i<m;i++) w[i]+=w[i-1];
    16     for (i=n-1;i>=0;i--) sa[--w[x[i]]]=i;
    17     for (p=1,j=1;p<n;m=p){
    18         for (p=0,i=n-j;i<n;i++) y[p++]=i;
    19         for (i=0;i<n;i++) if (sa[i]>=j) y[p++]=sa[i]-j;
    20         for (i=0;i<m;i++) w[i]=0;
    21         for (i=0;i<n;i++) w[wv[i]=x[y[i]]]++;
    22         for (i=1;i<m;i++) w[i]+=w[i-1];
    23         for (i=n-1;i>=0;i--) sa[--w[wv[i]]]=y[i];
    24         for (t=x,x=y,y=t,p=1,x[sa[0]]=0,i=1;i<n;i++)
    25         x[sa[i]]=cmp(y,sa[i-1],sa[i],j)?p-1:p++;
    26         }
    27     return;
    28 }
    29 void calheight(int *r,int *sa,int n){
    30      int i,j,k=0;
    31      for (i=1;i<=n;i++) rank[sa[i]]=i;
    32      for (i=0;i<n;height[rank[i++]]=k)
    33          for (k?k--:0,j=sa[rank[i]-1];r[i+k]==r[j+k];k++);
    34      return;
    35 }
    36 void rmq(int *rank,int n){
    37      int i,j;
    38      memset(f,127,sizeof(f));
    39      for (i=1;i<=n;i++) f[i][0]=height[i];
    40      for (j=1;j<20;j++)
    41          for (i=1;i+(1<<j)-1<=n;i++)
    42              f[i][j]=min(f[i][j-1],f[(1<<(j-1))+i][j-1]);
    43      return;
    44 }
    45 int get_rmq(int x,int y){
    46     int a=rank[x],b=rank[y];
    47     if (a>b) {int t=a; a=b; b=t;}
    48     a++;
    49     int t=int(log(double(b-a+1))/log(2.00));
    50     return min(f[a][t],f[b-(1<<t)+1][t]);
    51 }
    52 int main(){
    53     char s[maxn];
    54     cin >> s;
    55     n=strlen(s);
    56     int i,ans=0,k=0;
    57     for (i=0;i<n;i++) a[i]=s[i];
    58     a[n]=1;
    59     for (i=0;i<n;i++) a[i+n+1]=s[n-1-i];
    60     a[2*n+1]=0;
    61     da(a,sa,2*n+2,123);
    62     calheight(a,sa,2*n+1);
    63     rmq(rank,2*n+1);
    64     for (i=0;i<n;i++){
    65         int t=get_rmq(i,2*n-i)*2-1;
    66         if (t>ans) 
    67         {
    68                    ans=t;
    69                    k=i;
    70         }
    71         if (i>0) 
    72         {
    73                  t=get_rmq(i,2*n-i+1)*2;
    74                  if (t>ans) 
    75                  {
    76                             ans=t;
    77                             k=i;
    78                  }
    79         }
    80         }
    81     if (ans%2!=0) for (i=k-ans/2;i<=k+ans/2;i++) cout<<s[i];
    82     else for (i=k-ans/2;i<k+ans/2;i++) cout<<s[i];
    83     cout<<endl;
    84     return 0;
    85 }
    View Code
  • 相关阅读:
    bugfree3.0.1-修改“优先级”为中文引起的PHP Error
    【vue】vue单元测试:karma+mocha
    【node】node的核心模块---http模块,http的服务器和客户端
    【node】fs模块,文件和目录的操作
    【webpack】从零开始学webpack
    【vue】webpack插件svg-sprite-loader---实现自己的icon组件
    【vue】vue的路由权限管理
    【node】用koa搭建一个增删改服务(一)
    【小程序】小程序之发送模板消息
    【小程序】返回顶部wx.pageScrollTo和scroll-view的对比
  • 原文地址:https://www.cnblogs.com/xiaozhuyang/p/ural1297.html
Copyright © 2011-2022 走看看