zoukankan      html  css  js  c++  java
  • 牛客:14894最长回文

    传送门:最长回文

    题意:给你两个长度相等的字符串A和B,从A中选择一个可以为空的子串A[l1..r1],从B中选一个可以为空的子串B[l2..r2],满足r1=l2.然后把他们拼接在一起,求操作后的最长回文串的长度.

    题解:我们可以先对A和B进行manacher(马拉车)预处理,然后我们枚举回文中心,每次选A和B中最长的回文串的中心,然后向两边进行拓展,如果A的回文串的左边的字符可以在B的右边找到的话,就能够形成回文,每次维护一个最大值.(枚举时A和B要错开一个位置,因为是拼接而成的,自己在纸上对着样例写一写就知道为什么了)。

    代码:

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <cmath>
     5 #include <algorithm>
     6 #include <stack>
     7 #include <queue>
     8 #include <vector>
     9 #include <map>
    10 #include <set>
    11 #include <unordered_set>
    12 #include <unordered_map>
    13 #define ll long long
    14 #define fi first
    15 #define se second
    16 #define pb push_back
    17 #define me memset
    18 const int N = 1e6 + 10;
    19 const int mod = 1e9 + 7;
    20 using namespace std;
    21 typedef pair<int,int> PII;
    22 typedef pair<long,long> PLL;
    23 int n;
    24 int len;
    25 string s1,s2;
    26 char str1[N],str2[N];
    27 int p1[N],p2[N];
    28 
    29 void init(){
    30     int cnt=2;
    31     str1[0]='$';
    32     str1[1]='#';
    33     for(int i=0;i<n;++i){
    34         str1[cnt++]=s1[i];
    35         str1[cnt++]='#';
    36     }
    37     str1[cnt]='\0';
    38     cnt=2;
    39     str2[0]='$';
    40     str2[1]='#';
    41     for(int i=0;i<n;++i){
    42         str2[cnt++]=s2[i];
    43         str2[cnt++]='#';
    44     }
    45     str2[cnt]='\0';
    46 }
    47 
    48 void manacher(char *str,int *p){
    49     int id=0,mx=0;
    50      for(int i=0;i<len;++i){
    51          if(i<mx) p[i]=min(mx-i,p[2*id-i]);
    52          else p[i]=1;
    53          for(;str[i-p[i]]==str[i+p[i]];p[i]++);
    54          if(i+p[i]>mx){
    55              mx=i+p[i];
    56              id=i;
    57          }
    58      }
    59 
    60 }
    61 
    62 int main() {
    63     ios::sync_with_stdio(false);
    64     cin>>n>>s1>>s2;
    65     len=n*2+2;
    66     init();
    67     manacher(str1,p1);
    68     manacher(str2,p2);
    69 
    70     int ans=1;
    71     for(int i=2;i<=len;++i){
    72         int tmp=max(p1[i],p2[i-2]);
    73         while(str1[i-tmp]==str2[i+tmp-2]) tmp++;
    74             ans=max(ans,tmp);
    75     }
    76     printf("%d\n",ans-1);
    77 
    78     return 0;
    79 }
  • 相关阅读:
    git 还原某个文件~~~
    uniqid()
    array_filter 过滤一维中空数组,数组的序列不变
    加密 解密
    gitlab基本维护和使用
    vim 单文件中查找方法
    php数组定义
    $('.goods_tag_ids_all')[0].checked = true;//~~~~~ 单条改变checkbox 属性样式
    由买冰箱想到的
    2014年年终总结
  • 原文地址:https://www.cnblogs.com/lr599909928/p/12732075.html
Copyright © 2011-2022 走看看