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算法】
推荐阅读
- 离开美即
- 诱惑的世界
- 犯贱是场一往情深的万劫不复
- 北京地铁“人心脱轨”(大家都是平庸而又模棱两可的恶人啊…)
- 夏|夏 一年
- 企业为什么要融资
- 北京、北京
- 成都配资公司那家可靠()
- 马兆炜(小叮当影像)
- 北京妞儿|北京妞儿|关晓彤(全能型90后已出街,请小心避让)