Codeforces 25E 字符串hash模板题

来源:互联网 发布:治隆唐宋 知乎 编辑:程序博客网 时间:2024/05/18 10:15

题意

  • 三个字符串,问最短的把这三个字符串的作为子串的字符串长度。

思路

  • 三个字符串A(3,3)种排列方式,可以dfs,但是给定了三个,为方便起见,就手写了6种情况。
  • 先判断三个串互相有没有为子串的情况,作为子串的就可以不被考虑了。
  • 剩下的串,找前面串的后缀和后面串的前缀的最长公共部分。
  • 这可以完全用kmp解决,但是为了练习字符串hash,所以就这么写了~

实现

#include <cstdio>#include <cstring>#include <algorithm>#include <cmath>#include <string>#include <iostream>#include <map>using namespace std;string str[3];string strTmp;int type[6][3] = {0,1,2,0,2,1,1,0,2,1,2,0,2,0,1,2,1,0};typedef unsigned long long ull;const int maxn = 100005;//或者100000007,一般取奇数即可//先用长度比较,再用2~3个hash来判断,本题不需要这么做~ const ull B = 9973;const int inf = 0x3f3f3f3f;//判断str1后缀和str2前缀相等的最大长度 int cmp(string& str1,string& str2){    int ret = 0;    int len1 = str1.length();    int len2 = str2.length();    ull ah=0,bh=0,tmp=1;    for (int i=0;i<min(len1,len2);i++){        bh = bh * B + str2[i];        ah = ah + str1[len1-i-1] * tmp;        tmp *= B;        if (bh == ah){            ret = i+1;        }    }    return ret;}//判断str2是否为str1的子串 bool isInside(string& str1,string& str2){    int len1 = str1.length();    int len2 = str2.length();    ull t= 1;    for (int i=0;i<len2;i++)        t*=B;    ull ah = 0, bh = 0;    for (int i=0;i<len2;i++){        ah = ah * B + str2[i];        bh = bh * B + str1[i];    }    if (ah == bh)        return 1;    for (int i=0; i+len2 < len1 ;i++){        bh = bh * B + str1[i + len2] - str1[i] * t;        if (ah == bh)            return 1;    }    return 0;}int main(){    for (int i=0;i<3;i++)        cin>>str[i];    int ans = inf;    for (int i=0;i<6;i++){        int tmp = str[type[i][0]].length();        strTmp = str[type[i][0]];        for (int j=0;j<2;j++){            if (str[type[i][j+1]].length() <= strTmp.length()){                if (isInside(strTmp,str[type[i][j+1]]) == true){                    continue;                }            }            int tt = cmp(strTmp,str[type[i][j+1]]);            tmp += str[type[i][j+1]].length() - tt;            strTmp += str[type[i][j+1]].substr(tt,str[type[i][j+1]].length());        }        ans = min(ans,tmp);    }    cout << ans <<'\n';    return 0;}
0 0
原创粉丝点击