• 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
  • 相关阅读:
    Python self,init,对象属性
    Python 注释,类,属性,方法,继承
    Python 循环与定义函数
    PHP中封装Redis购物车功能
    负数字符串经过int处理之后还是负数
    小程序模板template
    PHP里获取一维数组里的最大值和最小值
    Python缩进与if语句 空格的魅力
    maven 建立ssh项目
    tomcat war包部署
  • 原文地址:https://www.cnblogs.com/lienus/p/4389953.html
Copyright © 2020-2023  润新知