zoukankan      html  css  js  c++  java
  • HDU5340——Manacher算法——Three Palindromes

    http://acm.hdu.edu.cn/showproblem.php?pid=5340

    /*
    Manacher算法:O(n) 实现最长回文子串
    算法实现:
    先向原字符串中插入一个原来串不存在的字符,一般用'#',再O(n)遍历一遍,用一个数组p[i]来记录以str[i]为中心的回文半径(注意str[i]是新串,长度为2*len+1),mx记录当前已有的回文最长到的位置,假定当前为i,j为i前面已经计算过的数,id为最长的回文的中心,那么可以得到一个方程 p[i] = min(p[2*id-i],mx - i),p[2*id-i]与p[i]是关于id对称的,那么p[i]的回文长度就是p[2*id-1]的回文长度,可是如果p[i]的长度超过了p[id]的mx,那么右边的就不确定了,然后再向外扩展
    
    
    */
    /************************************************
    * Author        :Powatr
    * Created Time  :2015-8-12 13:11:42
    * File Name     :Manacher.cpp
     ************************************************/
    
    #include <cstdio>
    #include <algorithm>
    #include <iostream>
    #include <sstream>
    #include <cstring>
    #include <cmath>
    #include <string>
    #include <vector>
    #include <queue>
    #include <deque>
    #include <stack>
    #include <list>
    #include <map>
    #include <set>
    #include <bitset>
    #include <cstdlib>
    #include <ctime>
    using namespace std;
    
    #define lson l, mid, rt << 1
    #define rson mid + 1, r, rt << 1 | 1
    typedef long long ll;
    const int MAXN = 1e5 + 10;
    const int INF = 0x3f3f3f3f;
    const int MOD = 1e9 + 7;
    
    int pre1[MAXN], pre2[MAXN];
    int p[MAXN];
    char s[MAXN];
    char str[MAXN];
    int n;
    void inti()
    {
        memset(str, 0, sizeof(str));
        memset(p, 0, sizeof(p));
        memset(pre1, 0, sizeof(pre1));
        memset(pre2, 0, sizeof(pre2));
         n = strlen(s+1);
        str[0] = '$';
         for(int i = 1; i <= n; i++){
             str[i*2-1] = '#';
             str[i*2] = s[i];
         }
         n = 2*n+1;
         str[n] = '#';str[n+1] = '';
    }
    
    void Manacher()
    {
        int mx = 0, id;
        for(int i = 1; i <= n; i++){
                if(mx > i) p[i] = min(p[2*id-i], mx-i);
                else p[i] = 1;
                for(; str[i+p[i]] == str[i-p[i]]; p[i]++);
                if(p[i] + i > mx){
                    mx = p[i] + i;
                    id = i;
                }
        }
    }
    
    bool check()
    {
        int cout1 = 0, cout2 = 0;
        for(int i = 1; i <= n; i++){
            if(p[i]  == i && i != 1){// printf("%d ", i);
                pre1[++cout1] = i;}
            if(i + p[i] - 1 == n  && i != n) pre2[++cout2] = i;
        }
        int l, r, mid;
        for(int i = 1; i <= cout1; i++){
            for(int j = 1; j <= cout2; j++){
                l = pre1[i] + p[pre1[i]] ;
                r = pre2[j] - p[pre2[j]] ;
                if(l > r) continue;
                mid = l + r >> 1;
                if(p[mid] > (r - l + 1 >> 1)){//这边是大于,因为p[mid]包含了自己
                    return true;
                }
            }
        }
        return false;
    }
    
    int main(){
        int T;
        scanf("%d", &T);
        while(T--){
            scanf("%s", s+1);
            n = strlen(s+1);
            if(n < 3) {printf("No
    ");continue;}
            inti();
            Manacher();
            if(check()) printf("Yes
    ");
            else printf("No
    ");
        }
        return 0;
    }
    

      

  • 相关阅读:
    使用 python 实现 memcached 的启动服务脚本 rc
    iNeedle系统之国舜项目
    CentOS系统在不重启的情况下为虚拟机添加新硬盘
    Windows下常用软件工具的命令
    dpdk在虚拟机上出错处理
    Linux工具之man手册彩色页设置
    使用VIM插件ctags来阅读C代码
    Linux命令行上传文件到百度网盘
    ng-repeat 的重复问题
    python 启动简单web服务器
  • 原文地址:https://www.cnblogs.com/zero-begin/p/4724658.html
Copyright © 2011-2022 走看看