HihoCoder1084: 扩展KMP(二分+hash,求T串中S串的数量,可以失配一定次数)
2018-03-07 19:22
369 查看
时间限制:4000ms
单点时限:4000ms
内存限制:256MB
在信息理论中,在两个相同长度的字符串之间的海明码距离是:两个字符串相同位置对应的字符不同的位置数目。换种说法,它表示将一个字符串转化为另一个字符串所需要改变字符的最小数目。
下面这些字符串之间的海明码距离:
"karolin"和"kathrin"是3.
"karolin"和"kerstin"是3.
1011101和1001001是2.
2173896和2233796是3.
现在给定两个字符串stra,strb,和一个整数k。对于stra中的一个子串,如果它的长度和strb的相同且它们之间的海明码距离不超过k,我们认为它们是匹配的。
那么我们想知道在stra中有多少子串是和strb是匹配的。
第一行是stra。
第二行是strb。
第三行是k。
请处理到文件末尾。
【参数说明】
1<=stra,strb的长度<=100000
stra,strb只包含小写字母
0<=k<=5
样例输入
样例输出
题意:求T串中S串的数量,最多可以失配K。
思路:len1=|S|,len2=|T|。枚举S的起点i,如果i后面的可行的长度>=len2,则累加1次。
具体实现:二分得到当前最长匹配长度,假设是L,则跳过L后面一位(失配的一位),同时失配次数累加一次,继续检测后面的。 如果匹配成功,而且跳过次数不超过K次,则满足。
Bkdrhash+二分: (题目是ExKMP,我没想到这么用扩展kmp来做,qwq。)
单点时限:4000ms
内存限制:256MB
描述
你知道KMP吗?它是用于判断一个字符串是否是另一个字符串的子串的算法。今天我们想去扩展它。在信息理论中,在两个相同长度的字符串之间的海明码距离是:两个字符串相同位置对应的字符不同的位置数目。换种说法,它表示将一个字符串转化为另一个字符串所需要改变字符的最小数目。
下面这些字符串之间的海明码距离:
"karolin"和"kathrin"是3.
"karolin"和"kerstin"是3.
1011101和1001001是2.
2173896和2233796是3.
现在给定两个字符串stra,strb,和一个整数k。对于stra中的一个子串,如果它的长度和strb的相同且它们之间的海明码距离不超过k,我们认为它们是匹配的。
那么我们想知道在stra中有多少子串是和strb是匹配的。
输入
有多组测试(大约100),每个用例占3行。第一行是stra。
第二行是strb。
第三行是k。
请处理到文件末尾。
【参数说明】
1<=stra,strb的长度<=100000
stra,strb只包含小写字母
0<=k<=5
输出
对于每个测试用例,以输出结果占一行。样例输入
abcde f 0 abcde f 1 karolin kathrin 3
样例输出
0 5 1
题意:求T串中S串的数量,最多可以失配K。
思路:len1=|S|,len2=|T|。枚举S的起点i,如果i后面的可行的长度>=len2,则累加1次。
具体实现:二分得到当前最长匹配长度,假设是L,则跳过L后面一位(失配的一位),同时失配次数累加一次,继续检测后面的。 如果匹配成功,而且跳过次数不超过K次,则满足。
Bkdrhash+二分: (题目是ExKMP,我没想到这么用扩展kmp来做,qwq。)
#include<cstdio> #include<cstring> #include<iostream> using namespace std; #define ull unsigned long long const int maxn=100000; const int seed=131; char a[maxn+10],b[maxn+10]; int hash1[maxn+10],hash2[maxn+10],g[maxn+10],K; int L1,L2,ans; int find(int w,int v) { int L=1,R=L2-v+1,res=0; while(L<=R){ int Mid=(L+R)>>1; if(hash1[w+Mid-1]-hash1[w-1]*g[Mid]==hash2[v+Mid-1]-hash2[v-1]*g[Mid]) res=Mid,L=Mid+1; else R=Mid-1; } return res; } bool check(int x) { int w=x,v=1; for(int i=1;i<=K;i++){ int L=find(w,v); w=w+L+1; v=v+L+1; if(v>L2) return true; } int L=find(w,v); w=w+L; v=v+L; if(v>L2) return true; return false; } int main() { g[0]=1; for(int i=1;i<=maxn;i++) g[i]=g[i-1]*seed; while(~scanf("%s%s%d",a+1,b+1,&K)){ L1=strlen(a+1); L2=strlen(b+1); ans=0; for(int i=1;i<=L1;i++) hash1[i]=hash1[i-1]*seed+a[i]; for(int i=1;i<=L2;i++) hash2[i]=hash2[i-1]*seed+b[i]; for(int i=1;i<=L1-L2+1;i++) if(check(i)) ans++; printf("%d\n",ans); } return 0; }
相关文章推荐
- HihoCoder1084:(二分+HASH)
- hihoCoder 1084 扩展KMP(后缀数组)
- hihocoder 1084 扩展KMP && 2014 北京邀请赛 Justice String
- LA-4513 - Stammering Aliens-(hash字符串+二分答案+hash排序) 找出子串出现次数
- [HDOJ 3518][Vjudge 10885] Boring counting [扩展kmp+Hash]
- extension是iOS8新开放的一种对几个固定系统区域的扩展机制,它可以在一定程度上弥补iOS的沙盒机制对应用间通信的限制。
- Codeforces-914F Substrings in a String (Bitset求T串中S串出现次数)
- 【bzoj3796】Mushroom追妹纸 Kmp+二分+Hash
- hdu6153 扩展kmp求一个字符串的后缀在另一个字符串出现的次数。
- hdu 3068 最长回文 (Manacher O(n) ) (扩展KMP和后缀数组也都可以做 O(nlogn))
- 比如你给它任意一个正整数,它可以按照一定的运算规则, 计算出得到1的最少操作次数。
- 正确lua简单的扩展,可以加速相关C++数据。
- HDU 6153 A Secret【扩展KMP】
- 扩展KMP
- 【KMP算法】KMP统计子串出现次数
- Hdu 5782 Cycle(拓展KMP+Hash)
- hdu 4300 扩展kmp+暴力枚举分割点
- hihocoder 1123 好配对 (二分)
- Enum扩展,可以包含多个属性
- hdu3613之扩展KMP