zoukankan      html  css  js  c++  java
  • 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
    ", x, y);
     75         for (int i=x; i<=y; i++)
     76             printf ("%c", a[i]);
     77         printf ("
    ");
     78     }
     79     else
     80         printf ("No solution!
    ");
     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 }
    本文为博主原创文章,未经博主允许不得转载。
  • 相关阅读:
    C# 文件过滤器Filter
    C#实现打印功能
    Entity Framework 批量插入很慢
    C#关于日期月天数和一年有多少周及某年某周时间段的计算
    lc.exe 已退出 代码为 1
    oracle获取本月第一天和最后一天及Oracle trunc()函数的用法
    [ASP.NET AJAX]How to register javascript functions after UpdatePanel updated
    PPC调用webservice精要
    Oracle的思维(4)Oracle的万能分页并不万能2
    Microsoft Tech ED 2006
  • 原文地址:https://www.cnblogs.com/alihenaixiao/p/4698843.html
Copyright © 2011-2022 走看看