Hdu 3294 Girls' research (manacher 最长回文串)

题目链接:

  Hdu 3294  Girls' research

题目描述:

  给出一串字符串代表暗码,暗码字符是通过明码循环移位得到的,比如给定b,就有b == a,c == b,d == c,.......,a == z。

问最长回文串所在区间,以及最长回文串所表示的明码。

解题思路:

  字符串长度[1,200000],用manacher算法很轻松就搞定了。

  get√新技能请点击me

 

  1 #include <cstdio>
  2 #include <string>
  3 #include <cstring>
  4 #include <iostream>
  5 #include <algorithm>
  6 #include <cmath>
  7 #include <queue>
  8 using namespace std;
  9 
 10 typedef long long LL;
 11 const int maxn = 410010;
 12 char a[maxn], b[maxn*2];
 13 int vis[maxn*2];
 14 
 15 void manacher (char s[], int len)
 16 {
 17     int l = 0;
 18     b[l ++] = '$';
 19     b[l ++] = '#';
 20     for (int i=0; i<len; i++)
 21     {
 22         b[l ++] = s[i];
 23         b[l ++] = '#';
 24     }
 25     b[l] = 0;
 26 
 27     /**
 28         vis[i],以i为中心的回文串,向两端延伸的长度
 29         mx为向后延伸最长的回文串延伸到的位置,id为其中心
 30 
 31     **/
 32 
 33     int mx = 0, id = 0, ans = 0, index;
 34     for (int i=0; i<l; i++)
 35     {
 36 
 37         /**
 38             i < mx,因为[id-vis[id],mx],所以i与id-(i-id)对称
 39             当i+vis[2*id-i] > mx时,vis[i] = mx - i;
 40 
 41             当i >= mx.......
 42 
 43             两端字符匹配时增加vis[i]
 44 
 45             更新id 和 mx
 46         **/
 47 
 48         vis[i] = mx > i ? min (vis[2*id-i], mx-i) : 1;
 49         while (b[i+vis[i]] == b[i-vis[i]])  vis[i] ++;
 50         if (i + vis[i] > mx)
 51         {
 52             mx = i + vis[i];
 53             id = i;
 54         }
 55         if (ans < vis[i])
 56         {
 57             ans = vis[i];
 58             index = i;
 59         }
 60     }
 61 
 62     /**
 63         每一个回文串都是以'#'为边界
 64         vis[i]是以i为第一个字母,向两边延伸的长度
 65         每一个字母在b数组中的偶数位置
 66     **/
 67 
 68     int x = index - vis[index] + 2;
 69     int y = index + vis[index] - 2;
 70     x = x / 2 - 1;
 71     y = y / 2 - 1;
 72     if (y != x)
 73     {
 74         printf ("%d %d\n", x, y);
 75         for (int i=x; i<=y; i++)
 76             printf ("%c", a[i]);
 77         printf ("\n");
 78     }
 79     else
 80         printf ("No solution!\n");
 81 }
 82 
 83 int main ()
 84 {
 85     char ch[2], vis[30];
 86     while (scanf ("%s %s", ch, a) != EOF)
 87     {
 88         int n = strlen (a);
 89 
 90         for (int i=0; a[i]; i++)
 91             {
 92                 a[i] -= ch[0] - 'a';
 93                 if (a[i] < 'a')
 94                     a[i] += 26;
 95             }
 96 
 97         manacher(a, n);
 98     }
 99     return 0;
100 }

 

posted @ 2015-08-03 11:18  罗茜  阅读(374)  评论(0编辑  收藏  举报