CF25E 字符串哈希/KMP

题意:
给定三个串,求包含这三个串的总串的最小长度。
思路:
字符串哈希。
当然,也可以用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;
}
    原文作者:KMP算法
    原文地址: https://blog.csdn.net/acunstoppable/article/details/77620233
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞