CFgym:Hidden Anagrams(Hash)

本文介绍了一种用于寻找两个字符串中最长相似子串的有效算法。该算法通过哈希值来快速判断两个子串是否由相同的字符组成及相同的数量,适用于长度不超过4000的字符串,时间限制为10秒。

题意:给两个字符串S和T,长度<=4000,找出各自最长的连续子串,使得两个子串的组成字母和其数量完全相同(即两子串排序后完全一样),Timelimit:10s。

思路:暴力找出S所有子串的Hash值,扔进set,从大到小枚举长度,在T中找。

//reference: weareateam
# include <bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef unsigned long long ull;
char s[4008], t[4008];
LL a[4008][28]={0}, b[4008][28]={0};
int slen, tlen;
int t1[4008], t2[4008];
unordered_set<ull>S;
bool check(int x)
{
    for(int i=1; i+x-1<=tlen; ++i)
    {
        ull r = 2333;
        for(int j=0; j<26; ++j) r += (r<<4)+b[i+x-1][j]-b[i-1][j];
        if(S.count(r)) return true;
    }
    return false;
}
int main()
{
    scanf("%s%s",s+1,t+1);
    slen = strlen(s+1);
    tlen = strlen(t+1);
    for(int i=1; i<=slen; ++i)
    {
        for(int j=0; j<26; ++j) a[i][j] = a[i-1][j];
        ++a[i][s[i]-'a'];
    }
    for(int i=1; i<=tlen; ++i)
    {
        for(int j=0; j<26; ++j) b[i][j] = b[i-1][j];
        ++b[i][t[i]-'a'];
    }
    for(int i=1; i<=slen; ++i)
    {
        for(int j=i; j<=slen; ++j)
        {
            ull r = 2333;
            for(int k=0; k<26; ++k) r += (r<<4)+a[j][k]-a[i-1][k];
            S.insert(r);
        }
    }
    int ans = min(slen, tlen);
    while(ans)
    {
        if(check(ans)) break;
        --ans;
    }
    printf("%d\n",ans);
    return 0;
}


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值