zoukankan      html  css  js  c++  java
  • Girls' research

    题目大意:给以一个字符串,求出来这个字符串的最长回文串,不过这个字符串不是原串,而是转换过的,转换的原则就是先给一个字符 例如 'b' 意思就是字符把字符b转换成字符 a,那么c->b, d->c.....a->z,大致就是这么个意思,然后求出最大回文串就行(回文串至少长度也得等于2)。
     
    分析:字符转换没什么可说的,求回文串可以使用Manacher算法,主要说一下怎么用 p数组保存的信息求原来的区间,因为p保存的是扩展串的匹配数目,p[i]就是保存的最大匹配值,我们可以先求出来它的最左端是 L=i-p[i]+1, 其实这个最左端保存的值一定是一个'#',因为‘#’总会被匹配成功,实际的串的位置肯定在这个字符的右边L+1,因为扩展的时候实际字符是按照i+i+2来计算的,所以还原的时候应该是 (L+1-2)/2,也就是(i-p[i])/2;
     
    代码如下:
    ==============================================================================================================
    #include<stdio.h>
    #include<string.h>
    #include<algorithm>
    using namespace std;
    
    const int MAXN = 1e6+7;
    const int oo = 1e9+37;
    
    char s[MAXN];
    int  p[MAXN];
    
    int Manacher(int len)
    {
        int id=0, Max=0;
    
        for(int i=2; i<len; i++)
        {
            p[i] = 1;
    
            if(p[id]+id > i)
                p[i] = min(p[id*2-i], p[id]+id-i);
    
            while( s[ i+p[i] ] == s[ i-p[i] ] )
                p[i]++;
    
            if(p[id]+id < p[i]+i)
                id = i;
    
            if(p[Max] < p[i])
                Max = i;
        }
    
        return Max;
    }
    
    int main()
    {
        char ch[10]={0};
    
        while(scanf("%s%s", ch, s) != EOF)
        {
            int i, k=ch[0]-'a';
            int N = strlen(s);
    
            for(i=N; i>=0; i--)
            {
                if(i != N)
                {
                    s[i] -= k;
                    if(s[i] < 'a')
                        s[i] += 26;
                }
                s[i+i+2] = s[i];
                s[i+i+1] = '#';
            }
            s[0] = '$';
    
            k = Manacher(N+N+1);
    
            if(p[k] <= 2)
                printf("No solution!
    ");
            else
            {
    
                int L = (k-p[k])/2, R = k+p[k];
    
                printf("%d %d
    ", L, L+p[k]-2);
    
                for(i=k-p[k]+1; i<R; i++)
                {
                    if(s[i] != '#')
                        printf("%c", s[i]);
                }
                printf("
    ");
            }
        }
    
        return 0;
    }
  • 相关阅读:
    selenium python 中浏览器操作
    wireshark基础学习—第三部分wireshark的过滤器语法
    wireshark基础学习—第二部分wireshark的基础操作
    wireshark基础学习—第一部分wireshark的基础知识
    Python 之 tuple
    Python 之 list
    python socketpool:通用连接池
    APScheduler 3.0.1浅析
    检查SDE版本健康情况的常用SQL语句
    免重启下刷新新添加的磁盘信息
  • 原文地址:https://www.cnblogs.com/liuxin13/p/4749902.html
Copyright © 2011-2022 走看看