zoukankan      html  css  js  c++  java
  • 回文串编辑

    【题目描述】

    操作包含两个步骤:

    第一步:写一个很长的字符串(只包含小写)在纸上。例如,"abcde",而是'a'里面是不是真正的'a',这意味着如果我们定义的'b'才是真正的'a',那么我们可以推断,'c'才是真正的'b' ,'d'才是真正的'c'······,'a'才是真正的'z'。根据这一点,字符串"abcde"变为"bcdef"。

    第二步:找出给定字符串中最长的回文串,回文字符串的长度必须等于或超过2。

    【输入描述】

    输入包含多个样例。

    每个样例包含两个部分,一个字符和字符串,它们由一个空格分隔,代表真正的'a'和字符串,字符串的长度不会超过200000,所有输入字符必须为小写。

    如果串的长度为n,它是从0标记为n-1。

    【输出描述】

    请以下两个步骤执行操作。

    如果你找到一个回文串,输出它的起始位置和结束位置,下一行输出此回文串,或输出“无解!”;

    如果有几个可用的答案,请选择其中最先出现的字符串。

    【输入样例】

    b babd

    a abcd

    【输出样例】

    0 2

    aza

    No solution!

    源代码:
    
    #include<cstdio>
    #include<cstring>
    #include<algorithm> //包含min()。
    using namespace std;
    char keyword,s[200001],sss[200001];
    int right,center,ans,num,point[200001]; //变量 right 表示当前回文子串的右边界,变量 center 表示当前回文子串的中心节点。
    int main() //Manmcher算法。
    {
        while (scanf("%c",&keyword)==1) //一直读入测试数据知道结束。
        {
            int key=keyword-'a'; //利用ASCII码来进行处理。
            memset(s,0,sizeof(s));
            memset(sss,0,sizeof(sss));
            memset(point,0,sizeof(point));
            right=0;
            center=0;
            num=0;
            ans=0; //全面初始化。
            char t;
            scanf("%c",&t); //除去空格。
            int length;
            scanf("%s",s);
            length=strlen(s);
            length=(length<<1)+1; //2*(string v1.0 的长度)+1=string v2.0的长度。
            for (int a=0;a<length;a++) //处理字符串。
              if (a&1)
                sss[a]=s[a>>1];
              else
                sss[a]='#';
            for (int a=0;a<length;a++) //依次处理字符。
            {
                point[a]=right>a?min(point[2*center-a],right-a):1; //如果已有回文子串右边界超过此节点,那么便有两种可能:以这个节点为中心的回文子串在这个大回文子串的范围内,或者超出这个范围。根据此理论将利用左对称点的信息来更新此节点。若不超过此节点,则只能普通处理。
                while (a>=point[a]&&sss[a+point[a]]==sss[a-point[a]]) //在允许的范围内进行边界的拓展。
                  point[a]++;
                if (point[a]>num) //更新最值。
                {
                    num=point[a];
                    ans=a;
                }
                if (a+point[a]>right) //若新的右边界更大,则更新。
                {
                    right=a+point[a];
                    center=a;
                }
            }
            if (ans<=1) //无回文子串。
              printf("No solution!
    ");
            else
            {
                int t1=(ans-point[ans]+2)>>1,t2=(ans+point[ans]-2)>>1; //可发现一规律:Point[i]=原以i为中心的回文子串长度+1。
                printf("%d %d
    ",t1,t2);
                for (int a=t1;a<=t2;a++) //进行字符替换与处理。
                    if (s[a]-key<'a')
                    printf("%c",'z'+s[a]-'a'-key+1);
                    else
                    printf("%c",s[a]-key);
                printf("
    ");
            }
        }
        return 0;
    }
  • 相关阅读:
    迁移学习——使用Tensorflow和VGG16预训模型进行预测
    AWK调用SHELL,并将变量传递给SHELL
    天津Uber优步司机奖励政策(1月18日~1月24日)
    南京Uber优步司机奖励政策(1月18日~1月24日)
    宁波Uber优步司机奖励政策(1月18日~1月24日)
    杭州(含嘉兴,绍兴,金华,湖州,义乌)Uber优步司机奖励政策(1月18日~1月24日)
    佛山Uber优步司机奖励政策(1月18日~1月24日)
    长沙Uber优步司机奖励政策(1月18日~1月24日)
    广州Uber优步司机奖励政策(1月18日~1月24日)
    西安Uber优步司机奖励政策(1月18日~1月24日)
  • 原文地址:https://www.cnblogs.com/Ackermann/p/5450916.html
Copyright © 2011-2022 走看看