zoukankan      html  css  js  c++  java
  • bunoj 34990(hash)

    传送门:Justice String

    题意:有两个串A,B,问是否存在A的一个子串S,S和B的长度相等,最多有2个字符不同。如果有多个,输出其实下标最小S的下标,没有输出-1。

    分析:从A每个位置开始找最长公共前缀,如果最长公共前缀长度不大于lenb,继续从下一次位置开始找,至多找两次,如果一直找不到就算不存在。

    #include <cstdio>
    #include <cstring>
    #include <string>
    #include <queue>
    #include <cmath>
    #include <algorithm>
    #define LL long long
    #define N 100010
    using namespace std;
    const LL mod=1000000007ll;
    const LL SEED=131;
    char a[N],b[N];
    int lena,lenb;
    unsigned LL hha[N],hhb[N];
    unsigned LL p[N];
    void init()
    {
        hha[0]=a[0];
        hhb[0]=b[0];
        for(int i=1;i<lena;i++)
        {
            hha[i]=hha[i-1]*SEED+a[i];
        }
        for(int i=1;i<lenb;i++)
        {
            hhb[i]=hhb[i-1]*SEED+b[i];
        }
    }
    LL calc(int x,int len,unsigned LL f[])
    {
        return f[x+len-1]-f[x-1]*p[len];
    }
    int lcp(int pa,int pb)
    {
        int l=0,r=lenb-pb,ans;
        while(l<=r)
        {
            int m=(l+r)>>1;
            if(calc(pa,m,hha)==calc(pb,m,hhb))
                l=m+1,ans=m;
            else r=m-1;
        }
        return ans;
    }
    int main()
    {
        int T,cas=1;
        p[0]=1ll;
        for(int i=1;i<N;i++)p[i]=p[i-1]*SEED;
        scanf("%d",&T);
        while(T--)
        {
            scanf("%s%s",a,b);
            lena=strlen(a);
            lenb=strlen(b);
            init();
            int ans=-1;
            for(int i=0;i<=lena-lenb;i++)
            {
                int num=0;
                num+=lcp(i+num,num);
                if(num>=lenb)
                {
                    ans=i;break;
                }
                num++;
                if(num>=lenb)
                {
                    ans=i;break;
                }
                num+=lcp(i+num,num);
                if(num>=lenb)
                {
                    ans=i;break;
                }
                num++;
                if(num>=lenb)
                {
                    ans=i;break;
                }
                num+=lcp(i+num,num);
                if(num>=lenb)
                {
                    ans=i;break;
                }
            }
            printf("Case #%d: %d
    ",cas++,ans);
        }
    }
    View Code
  • 相关阅读:
    php实现cookie加密解密
    三个php加密解密算法
    一个经典的PHP加密解密算法
    Webpack 核心模块 tapable 解析(转)
    详解基于vue,vue-router, vuex以及addRoutes进行权限控制
    编写一个插件
    详解css3 pointer-events(阻止hover、active、onclick等触发事件来
    Dockerfile HEALTHCHECK详解
    Dockerfile 指令 WORKDIR介绍
    NPM私有包部署到私有仓库
  • 原文地址:https://www.cnblogs.com/lienus/p/4389953.html
Copyright © 2011-2022 走看看