• CF25E:Test——题解


    https://vjudge.net/problem/CodeForces-25E

    题目大意:给三个字符串,求最小串,使得前三个串都是它的子串。

    ————————————————

    这题虽然是看哈希的时候做的,但上网一查啊全是KMP。

    所以果断用KMP做啦!

    (话说网上的题解长得都一模一样一个字都没改所以就不贴了)

    对于三个串共六种排法,排列组合一下然后在把他们重合的部分减去就会是答案。

    而发现对于两个字符串ab去重,我们有两种情况:

    1.a的尾部是b的头部:

    通过KMP解决,输出KMP后(即a被匹配完了)b被匹配到哪里了,即是ab重合长度。

    2.b是a的子串:

    上述KMP还有一个目的就是为了判断是否为子串,如果是的话,跳过b,a和下一个字符串相接。

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    const int INF=2147483647;
    int nxt[4][100001]={0};
    bool ok[4];
    void getnext(int m,char s2[],int t){
        int j=0;
        for(int i=2;i<=m;i++){
            while(j!=0&&s2[j+1]!=s2[i])j=nxt[t][j];
            if(s2[j+1]==s2[i])j++;
            nxt[t][i]=j; 
        }
        return;
    }
    int KMP(int n,int m,char s1[],char s2[],int t){
        int j=0,cnt=0;
        for(int i=1;i<=n;i++){
            while(j!=0&&s2[j+1]!=s1[i])j=nxt[t][j];
            if(s2[j+1]==s1[i])j++;
            if(j==m){
            return -1;
            j=nxt[t][j];
            }
        }
        return j;
    }
    char s[4][100001];
    int len[4];
    int K[4][4];
    int main(){
        scanf("%s%s%s",s[1]+1,s[2]+1,s[3]+1);
        len[1]=strlen(s[1]+1);
        len[2]=strlen(s[2]+1);
        len[3]=strlen(s[3]+1);
        for(int i=1;i<=3;i++){
        getnext(len[i],s[i],i);
        for(int j=1;j<=3;j++){
            if(i==j)continue;
            K[j][i]=KMP(len[j],len[i],s[j],s[i],i);
        }
        }
        int ans=INF;
        for(int i=1;i<=3;i++){
        for(int j=1;j<=3;j++){
            for(int k=1;k<=3;k++){
            if(i==j||j==k||i==k)continue;
            int sum=len[i]+len[j]+len[k]-K[i][j]-K[j][k];
            if(K[i][j]>=0&&K[j][k]>=0)ans=min(ans,sum);
            else{
                if(K[i][j]<0&&K[i][k]<0)ans=min(ans,len[i]);
                else if(K[i][j]<0)ans=min(ans,sum+K[i][j]+K[j][k]-len[j]-K[i][k]);
                if(K[j][k]<0)ans=min(ans,sum+K[j][k]-len[k]);
            }
            }
        }
        }
        printf("%d
    ",ans);
        return 0;
    }
  • 相关阅读:
    让一个不固定高度的div,保持垂直水平居中的方法
    Set、Map、WeakSet 和 WeakMap
    JS 中常用的 Math 方法
    不使用 new,创建一个实例对象
    做一个弹窗
    变量提升
    事件委托实践
    vue组件通信
    新版vue脚手架关闭eslint
    图片懒加载原生js实现
  • 原文地址:https://www.cnblogs.com/luyouqi233/p/8011183.html
Copyright © 2020-2023  润新知