zoukankan      html  css  js  c++  java
  • Finding Palindromes POJ

    题目链接

    题意:n个字符串,两两拼接能最多形成多少种,自己可以和自己拼接。

    思路:设a,b两个串要拼接判断其是否为回文串分三种情况考虑:

    第一种:alen < blen a是b的反串前缀,且b的剩余部分可以认为是后缀是回文串

    第二种:alen > blen b的反串是a的前缀,且a的后缀是回文串

    第三种:alen == blen a就是b反串。

    根据上面的三种情况我们要求出字符串是否为另一个前缀,还有就是其后缀是否为回文串。所以可以想到马拉车算法和字典树。正串建立字典树,反串去进行匹配。

    #include<stdio.h>
    #include<math.h>
    #include<string.h>
    #include<map>
    #include<algorithm>
    #define N 200060
    #define ll long long
    using namespace std;
    const int maxn=2000110;
    char a[maxn],text[maxn*2];
    int P[maxn*2];
    int trie[maxn][28],End[maxn],hou[maxn];
    int n,root,ans,idx;
    struct point
    {
        int len;
        int st;
    }b[maxn];
    void pre_treat(){
        int len = strlen(a);
        for(int i=0;i<len;i++){
            text[i*2] = '#';
            text[i*2+1] = a[i];
        }
        text[len*2]='#';text[len*2+1]='';
    }
    void manacher(){
        P[0] = 1;                                   //第一个字符的回文串肯定是1
        int len = strlen(text);
        int md = 0;
        for(int i=1;i<len;i++){
            if(i<md+P[md]){
                int k = P[md*2-i];                  //找到对称点的回文串长度
                if(i+k<md+P[md]) P[i] = k;          //回文串没有超过右界
                else{
                    k = md+P[md]-i;
                    while(i+k<len&&i+k>=0&&text[i+k]==text[i-k]) k++;
                    md = i;
                    P[i] = k;
                }
            }
            else{
                int k = 1;
                while(i+k<len&&i+k>=0&&text[i+k]==text[i-k]) k++;
                md = i;
                P[i] = k;
            }
        }
    }
    
    void Insert()
    {
    //    printf("%s
    ",text);
        for(int i=0;i<n;i++)
        {
            int now=root;
            for(int j=b[i].st;j<b[i].st+b[i].len;j++){
                if(!trie[now][a[j]-'a']) trie[now][a[j]-'a']=++idx;
                now=trie[now][a[j]-'a'];
                int mid=((j)*2-1+(b[i].st+b[i].len-1)*2+1)/2;
                if(P[mid]>mid-(j+2)*2+2)
                    hou[now]++;
            }
            hou[now]--;
                                               
            End[now]++;
        }
    }
    void Find()
    {
        for(int i=0;i<n;i++)
        {
            int now=root;
            for(int j=b[i].st+b[i].len-1;j>=b[i].st;j--)
            {
            //    printf("j:%d
    ",j);
                if(!trie[now][a[j]-'a']){
                    now=-1;
                    break;
                }
                now=trie[now][a[j]-'a'];
                if(End[now])
                {
                    int mid=(b[i].st*2-1+(j)*2+1)/2;
                    //printf("mid:%d %d
    ",P[mid],mid-b[i].st*2+1-2+1);
                    if(P[mid]>mid-b[i].st*2){
                        ans+=End[now];
                      //  printf("End:%d
    ",End[now]);
                    }
                }
            }
            if(now!=-1){ans+=hou[now];
          //  printf("hou:%d
    ",hou[now]);
        }
        }
    }
    
    int main()
    {
        while(~scanf("%d",&n))
        {
            memset(trie,0,sizeof(trie));
            memset(hou,0,sizeof(hou));
            memset(End,0,sizeof(End));
            int len1=0;
            root=0,ans=0,idx=0;
            for(int i=0;i<n;i++)
            {
                scanf("%d",&b[i].len);
                scanf("%s",a+len1);
                b[i].st=len1;
                len1+=b[i].len;
            }
            pre_treat();
            manacher();
            Insert();
            Find();
            printf("%d
    ",ans);
        }
     } 
  • 相关阅读:
    2020年秋招联发科小米等20家公司面经总结
    一个普通硕士生的2020秋招总结(文末送福利)
    Linux内核中container_of宏的详细解释
    拒绝造轮子!如何移植并使用Linux内核的通用链表(附完整代码实现)
    UWB硬件设计相关内容
    SpringToolSuit(STS)添加了Lombok后仍然报错
    Spring Boot整合Mybatis出现错误java.lang.IllegalStateException: Cannot load driver class:com.mysql.cj.jdbc.Driver
    Word快捷选取
    微服务下的用户登录权限校验解决方案
    Spring Boot 使用Mybatis注解开发增删改查
  • 原文地址:https://www.cnblogs.com/2462478392Lee/p/13669504.html
Copyright © 2011-2022 走看看