zoukankan      html  css  js  c++  java
  • POJ

    Description
    Andy the smart computer science student was attending an algorithms class when the professor asked the students a simple question, "Can you propose an efficient algorithm to find the length of the largest palindrome in a string?"

    A string is said to be a palindrome if it reads the same both forwards and backwards, for example "madam" is a palindrome while "acm" is not.

    The students recognized that this is a classical problem but couldn't come up with a solution better than iterating over all substrings and checking whether they are palindrome or not, obviously this algorithm is not efficient at all, after a while Andy raised his hand and said "Okay, I've a better algorithm" and before he starts to explain his idea he stopped for a moment and then said "Well, I've an even better algorithm!".

    If you think you know Andy's final solution then prove it! Given a string of at most 1000000 characters find and print the length of the largest palindrome inside this string.

    Input
    Your program will be tested on at most 30 test cases, each test case is given as a string of at most 1000000 lowercase characters on a line by itself. The input is terminated by a line that starts with the string "END" (quotes for clarity).

    Output
    For each test case in the input print the test case number and the length of the largest palindrome.

    Sample Input

    abcbabcbabcba
    abacacbaaaab
    END

    Sample Output

    Case 1: 13
    Case 2: 6

    题目大意:求最长回文串

    对于最长回文串,有一个时间和空间都是O(n)的算法,叫manacher算法

    首先我们在每个字符两边都加入一个#,然后不管奇回文串还是偶回文串就都变成了奇回文串

    然后我们求一个数组p[i],表示以i为中心的回文串最多往右侧延伸多长

    关键就是怎么求这个p数组

    假设我们已经求出了p[1]到p[i-1],我们记录一个回文串右端最右边的右端点和中心,分别记为maxr和id

    如果这个右端点超过了i(maxr>i),那么我们可以先算出p[i]的一个初始值,即i在在这个回文串中对应的位置j的p[j]

    但是这个不一定是对的,因为以j为中心的回文串不一定被以id为中心的回文串所包含,所以还要与maxr-i做一个min

    然后再向两边扩展

    可以证明这个是O(n)的

    假设maxr小于i,那么从i往右暴力扩展,同时会更新maxr

    如果maxr大于i,那么以i为中心的回文串就有可能确定了,不能再向两边扩展了,那么这个操作是O(1)的

    如果没有确定那么以i为中心的初始回文串就一定是延伸到了maxr,然后暴力扩展

    maxr一直是递增的,最多增加到n,所以扩展的操作加起来是O(n)的

    所以就是O(n)的时间了

     1 const
     2     maxn=1000010;
     3 var
     4     f:array[0..maxn*2]of longint;
     5     a:array[0..maxn*2]of byte;
     6     s:ansistring;
     7     time:longint;
     8 
     9 function min(x,y:longint):longint;
    10 begin
    11     if x<y then exit(x);
    12     exit(y);
    13 end;
    14 
    15 procedure work;
    16 var
    17     max,id,i,ans:longint;
    18 begin
    19     for i:=1 to length(s) do
    20       a[i<<1]:=ord(s[i]);
    21     max:=0;
    22     id:=0;
    23     for i:=1 to length(s)<<1+1 do
    24       begin
    25         if max>i then f[i]:=min(f[2*id-i],max-i)
    26         else f[i]:=1;
    27         while a[i+f[i]]=a[i-f[i]] do
    28           inc(f[i]);
    29         if i+f[i]>max then
    30         begin
    31           max:=i+f[i];
    32           id:=i;
    33         end;
    34       end;
    35     ans:=0;
    36     for i:=1 to length(s)<<1+1 do
    37       if f[i]-1>ans then ans:=f[i]-1;
    38     writeln('Case ',time,': ',ans);
    39 end;
    40 
    41 begin
    42     readln(s);
    43     a[0]:=200;
    44     while s<>'END' do
    45       begin
    46         inc(time);
    47         work;
    48         readln(s);
    49       end;
    50 end.
    View Code
  • 相关阅读:
    nth-of-type()的用法
    H5禁止底部横向滚动条,使一个元素居中
    CRM项目-1模型与站点管理
    django-debug-toolbar
    python发送邮件
    os 模块
    Django(三) ORM操作
    Django框架初识
    JS 正则表达式
    前端-高潮 jQuery
  • 原文地址:https://www.cnblogs.com/Randolph87/p/3641412.html
Copyright © 2011-2022 走看看