2014北京邀请赛 J 题 基于哈希值的LCP算法

题意:给定a和b两个字符串,有b匹配a在允许有两个字母不匹配而其他全匹配的情况下,找出第一个匹配的位置,若不能匹配,返回-1;
simple input
3
aaabcd
abee


aaaaaa
aaaaa


aaaaaa
aabbb


simple output
Case #1: 2
Case#2:0
Case#3:-1
解题思路:
首先将b串接到a串的后面,利用LCP算法,进行匹配,中间最多有两次匹配不成功。

#include #include #include #include using namespace std; typedef unsigned long long int ULL; const int SIZE = 100003; const int SEED = 13331; const int maxn = 600100; char s[maxn]; ULL H[maxn]; ULL XL[maxn]; int len; void build(char *s) //求出字符串哈希值函数模板O(n) { len=strlen(s); H[len]=0; XL[0]=1; for (int i=len-1; i>=0; i--) { H[i]=H[i+1]*SEED+s[i]; XL[len-i]=XL[len-i-1]*SEED; } } ULL hash(int i,int L) //返回以i为开头的长度为L的字符串的哈希值(比较两个字符串的哈希值是否相等就可以判定两个字符串是不是相等)O(lgn) { return H[i]-H[i+L]*XL[L]; }int lcp(int i,int j)//二分,返回求取的以i和j开头的字符串的最大匹配的长度 { int l=0,r=min(len-i,len-j); int res=0; while (l<=r) { int mid=(l+r)/2; if (hash(i,mid)==hash(j,mid)) { res=mid; l=mid+1; } else { r=mid-1; } } return res; }char A[maxn],B[maxn]; int main() { int T; int cas=0; scanf("%d",&T); while (T--) { cas++; scanf("%s%s",A,B); int len1=strlen(A); int len2=strlen(B); if (len1=n)//匹配到末尾了,下同 { ans=i; break; } st++; ed++; //第一次匹配不成功 if (ed>=n) { ans=i; break; } tmp=lcp(st,ed); st+=tmp; ed+=tmp; if (ed>=n) { ans=i; break; } st++; ed++; //第二次匹配不成功 if (ed>=n) { ans=i; break; } tmp=lcp(st,ed); st+=tmp; ed+=tmp; if (ed>=n) { ans=i; break; } } printf("Case #%d: %d\n",cas,ans); } return 0; }




【2014北京邀请赛 J 题 基于哈希值的LCP算法】

    推荐阅读