CF25E 字符串哈希/KMP

来源:互联网 发布:mac能用淘宝千牛吗 编辑:程序博客网 时间:2024/06/05 20:49

题意:
给定三个串,求包含这三个串的总串的最小长度。
思路:
字符串哈希。
当然,也可以用KMP,然而我自己没有想到,看来对KMP的理解仍然不够深。
这里也引用一下其他博主的KMP做法。
http://blog.csdn.net/u011345136/article/details/38400395
实现:

#include <bits/stdc++.h>using namespace std;typedef unsigned long long ull;const ull B = 1e8 + 7;const int MAX_SIZE = 1e5 + 10;const int INF = 0x3f3f3f3f;char s[3][MAX_SIZE];int ans;int type[6][3] = {0,1,2,0,2,1,1,0,2,1,2,0,2,0,1,2,1,0};bool contain(char* a, char* b)//a是否在b中出现过{    int al = strlen(a), bl = strlen(b);    if(al > bl) return false;    //计算B的al次方    ull t = 1;    for(int i = 0; i < al; i++) t *= B;    //计算a和b长度为al的前缀对应的哈希值    ull ah = 0, bh = 0;    for(int i = 0; i < al; i++) ah = ah * B + a[i];    for(int i = 0; i < al; i++) bh = bh * B + b[i];    //对b不断右移一位,更新哈希值并判断    for(int i = 0 ; i + al <= bl; i++)    {        if(ah == bh) return true; //b从位置i开始长度为al的字符串子串等于a        if(i + al < bl) bh = bh * B + b[i + al] - b[i] * t;    }    return false;}//a的后缀和b的前缀相等的最大长度int overlap(char* a, char* b){    int al = strlen(a), bl = strlen(b);    int ans = 0;    ull ah = 0, bh = 0, t = 1;    for(int i = 1; i <= min(al, bl); i++)    {        ah = ah + a[al - i] * t;        bh = bh * B + b[i - 1];        if(ah == bh) ans = i;        t *= B;    }    return ans;}void solve(){    ans = INF;    int l1 = 0, l2 = 0;    for(int i = 0; i < 6; i++)    {        if(contain(s[type[i][0]], s[type[i][1]]))        {            l1 = strlen(s[type[i][0]]);        }        else        {            l1 = overlap(s[type[i][0]], s[type[i][1]]);        }        if(contain(s[type[i][2]], s[type[i][1]]))        {            l2 = strlen(s[type[i][2]]);        }        else        {            l2 = overlap(s[type[i][1]], s[type[i][2]]);        }        ans = min(ans, (int)(strlen(s[0]) + strlen(s[1]) + strlen(s[2]) - l1 - l2));    }    cout << ans << endl;}int main(){    ios::sync_with_stdio(false);    cin.tie(0);    cin >> s[0] >> s[1] >> s[2];    solve();    return 0;}
原创粉丝点击