洛谷 P2957 字符串哈希入门

题目链接
题目描述
奶牛们非常享受在牛栏中哞叫,因为她们可以听到她们哞声的回音。虽然有时候并不能完全听到完整的回音。Bessie曾经是一个出色的秘书,所以她精确地纪录了所有的哞叫声及其回声。她很好奇到底两个声音的重复部份有多长。

输入两个字符串(长度为1到80个字母),表示两个哞叫声。你要确定最长的重复部份的长度。两个字符串的重复部份指的是同时是一个字符串的前缀和另一个字符串的后缀的字符串。

我们通过一个例子来理解题目。考虑下面的两个哞声:

moyooyoxyzooo

yzoooqyasdfljkamo

第一个串的最后的部份"yzooo"跟第二个串的第一部份重复。第二个串的最后的部份"mo"跟第一个串的第一部份重复。所以"yzooo"跟"mo"都是这2个串的重复部份。其中,"yzooo"比较长,所以最长的重复部份的长度就是5。

输入格式

  • Lines 1…2: Each line has the text of a moo or its echo

输出格式

  • Line 1: A single line with a single integer that is the length of the longest overlap between the front of one string and end of the other.

Sample input

abcxxxxabcxabcd 
abcdxabcxxxxabcx 

Sample output
11

其实这题用暴力的方法也能做,这里用哈希纯属就是为了练习题目算法QAQ

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define rep(i,a,b) for(int i=a;i<=b;i++)
typedef long long ll;
typedef unsigned long long ull;
using namespace std;
//const ll INF=0x3f3f3f3f3f3f3f3f;
const int INF=0x3f3f3f3f;
const int N=1e5+10;
ull base=131;
ull ha[N*10];
char str1[N*10],str2[N*10];
int main()
{
    #ifndef ONLINE_JUDGE
    freopen("in.txt","r",stdin);
    #endif // ONLINE_JUDGE
    scanf("%s%s",str1,str2);
    int len1=strlen(str1),len2=strlen(str2);
    ha[0]=1;
    for(int i=1;i<=max(len1,len2);i++) ha[i]=ha[i-1]*base;
    ull t2=0,t1=0;
    int i=0,j=len2-1;
    int tans=0,ans=0;
    while(i<len1 && j){
        t1=t1*base+str1[i];
        t2=str2[j]*ha[i]+t2;
        if(t1==t2)
            tans=i+1;
        i++;j--;
    }
    j=0;i=len1-1;
    t2=t1=0;
    while(j<len2 && i){
        t2=t2*base+str2[j];
        t1=str1[i]*ha[j]+t1;
        if(t1==t2)
            ans=j+1;
            j++;i--;
    }
    printf("%d\n",max(ans,tans));
    return 0;
}


这篇文章也是类似的做法:https://blog.csdn.net/c___c18/article/details/100144266

你可能感兴趣的:(哈希)