• HDU-3068-最长回文


    这题好像只能用mancher算法解决,速成马拉车算法。
    这个算法的核心思想就是,如果当前要维护的下标i小于上一次经维护后的max值,我们就取上一次得到的对称位置的回文半径。
    这个回文半径就是min(p[ id * 2 - i] , max-i),它的意思就代表了,我们先取其中最小的一个半径,然后我们之后再暴力向后拓展。
    因为我们下一步是暴力,所以我们上一步取一个小值即可。括号中的两个表达式的意思是,它的对称位置 由 中心位置
    id-(i-id) 得到,所以就取它对称位置的回文半径值,要么就是上次拓展的最大位置减去i值,它们两个中取一个最小值,
    这样我们就不必暴搜之前的那么多次了。我们只用搜索之后的就可了。
    但是在我们维护之前,我们可以看到,如果我们维护奇数长度的子串的时候,还是很方便的,所以当我们维护偶数长度的时候,我们就把偶数变奇数即可。
    我们在每次字符之间加上一个#,这样的话,如果是偶数长度,中间就有奇数个间隙,左右两边共有两个#,偶数加偶数加奇数,就是奇数。对于奇数长度同理。
    然后我们求的这个数组p里面求的其实是半径值,而我们之前把原子串扩展了1倍,所以而我们求的半径值减一就是原子串的直径。
    这就是马拉车算法的思路,其实和KMP还是蛮像的。

    #include <cstdio>
    #include <cstring>
    const int maxn = 3e5;
    char s[maxn], str[maxn];
    int len1, len2, p[maxn], ans;
    
    int min(int x,int y)
    {
        return x < y ? x : y;
    }
    
    void init()
    {
        memset(p, 0, sizeof(p));
        str[0] = '$';
        str[1] = '#';
        for (int i = 0; i < len1;i++) {
            str[i * 2 + 2] = s[i];
            str[i * 2 + 3] = '#';
        }
        len2 = len1 * 2 + 2;
        str[len2] = '*';
    } 
    
    void Manacher()
    {
        int id = 0, mx = 0;
        for (int i = 1; i < len2;i++) {
            if (i<mx)
                p[i] = min(p[2 * id - i], mx - i);
            else
                p[i] = 1;
            //直接取出它的最小回文半径,然后我们再拓展它
            while (str[i-p[i]]==str[i+p[i]])
                p[i]++;
            if (p[i]+i>mx) {
                mx = p[i] + i;
                id = i;
            }
        }
    }
    
    int main()
    {
        while (scanf("%s",s)!=EOF) {
            len1 = strlen(s);
            init();
            Manacher();
            ans = 0;
            for (int i = 1; i < len2;i++) {
                if (p[i]>ans)
                    ans = p[i];
            }
            printf("%d
    ", ans-1);
        }
    }
    
  • 相关阅读:
    sql server分布式事务解决方案 (笔记)
    深入理解Datatable(笔记)
    SQLSERVER 2005 实现文件读写操作
    局部变量、全局变量、堆、堆栈、静态和全局
    分布式事务DISTRIBUTED TRANSACTION
    SQLSEVER2005中找不到存储过程xp_getfiledetails 解决办法
    模式窗口
    理解析构函数的执行过程
    Oracle分页
    DataTable导出到Excel、GSV (转)
  • 原文地址:https://www.cnblogs.com/xyqxyq/p/10366584.html
Copyright © 2020-2023  润新知