
目录
前言
题目详情
简单分析
注意事项
完整代码
AC凭证
水话
前言
学习了之前所发的有关字符串哈希的相关讲解,相信有一部分同学已经按捺不住赶紧上手刷上那么几题了呢!然后本蒟蒻在今天考完机考,马上就拿上了电脑开启了相关的刷题,没想到一个普及组的题目刷了有一个半小时之久,利用昨天一位很厉害的学长说的话:菜是原罪!如果不知道字符串哈希是什么的uu们点击这里:字符串哈希(嘻嘻)!
题目详情原题是一个英文题目,但是洛谷官网把它翻译了,这是本题的链接:洛谷题目p2957
简单分析因为已经有了字符串哈希的基础,所以此题,其实只用算出字符串a的前缀和后缀以及字符串b的前缀和后缀的哈希值就可以了,然后进行两次比较,最终得出最长的重复字串个数!
注意事项不知道看到这的同学们,在思考的时候会不会想,我们这个题目最终可不可以利用二分答案的方法去找到最终的那个最长的答案,我刚开始也是那么想的,结果一个小时都在找此题利用二分的错误在哪。大家可以再自习读读题目,由于题目的特殊性,此题都是在求前缀和后缀,如果用二分的话,那就是一个在找是否存在最长重复子串的问题了,这和我们去计算后缀的哈希值的思想是完全不符合的,最终当然不会得到正确的答案啦!
完整代码#includeusing namespace std; int mod=13331,k=26; //利用mod防止数字溢出,k表示在26进制下的哈希值 string a,b; int sum=0; long long a1[100]; //记录a字串的哈希值 long long b1[100]; //记录b字串的哈希值 //计算前缀的哈希值 long long hash1(string s,int len) { long long ans1=0; for(int i=0;i >a>>b; int len1=a.length(); int len2=b.length(); //最终答案一定不会超过两字串较小长度的那一个长度 int minl=min(len1,len2); //sum记录下最终的答案 int sum=0; //sum1 表示a的前缀与b的后缀最长相等的个数 //sum2 表示b的前缀与a的后缀最长相等的个数 int sum1=0,sum2=0; //计算a的前缀和b的后缀。 for(int i=1;i<=minl;i++) { a1[i]=hash1(a,i); b1[i]=hash2(b,i,len2); if(a1[i]==b1[i]) sum1=i; } //计算a的后缀和b的前缀 for(int i=1;i<=minl;i++) { b1[i]=hash1(b,i); a1[i]=hash2(a,i,len1); if(a1[i]==b1[i]) sum2=i; } //输出sum1,sum2的最大的那一个 sum=max(sum1,sum2); cout< AC凭证 水话 本蒟蒻已经分专栏了哦,相信大家会更加清晰的找到对应的块进行阅读,然后呢封面是自己设计的,虽然比较丑,但是嘛我觉得还是很可爱的哈哈哈!
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)