codeforces 762 C. Two strings

关于字符串前缀和后缀的题目

第一点就是从B 串中删除一段连续的子串,结果就是把B串分为三段,如下所示:

| 左边部分 || 删除部分 || 右边部分 |

第二点就是pre数组和suf数组,这里是前缀数组和后缀数组,以实例来解释数组的含义:
以pre数组为例

设A=abacaba,B=abcdcba,串的下标从1开始,枚举A 的每一个字符

pre[ 0 ]=0 ,//作为监视哨

pre[ 1 ]=1 , //A[1]=B[1]

pre[ 2 ]=2 ,//A[2]=B[2]

pre[ 3 ]=2 ,//A[3]!=B[3],所以pre[3]=pre[2]

pre[ 4 ]=3 ,//A[4]=B[3],pre[4]=3

pre[ 5 ]=3 ,

pre[ 6 ]=3 ,

pre[ 7 ]=3 

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<string>
#include<vector>
#define DEBUG(x) cout<<#x<<" = "<<x<<endl
using namespace std;
const int MAXN=1e5+10;
char A[MAXN];
char B[MAXN];
int pre[MAXN];
int suf[MAXN];
int main()
{
//    freopen("in.txt","r",stdin);
    scanf("%s",A+1);
    scanf("%s",B+1);
    int la=strlen(A+1),lb=strlen(B+1);
    int ptr=1;
    for(int i=1;i<=la ;i++ ){
        if(A[i]==B[ptr]){
            pre[i]=ptr;
            ptr++;
        }
        else pre[i]=pre[i-1];
    }
    ptr=lb;
    suf[la+1]=lb+1;///后缀从右边开始,pre[0]和suf[la+1]监视哨
    for(int i=la;i>=1 ;i-- ){
        if(A[i]==B[ptr]){
            suf[i]=ptr;
            ptr--;
        }
        else suf[i]=suf[i+1];
    }
    int a,b,l=-1;
    for(int i=1;i<=la+1 ;i++ ){///从1开始,0作为监视哨
        if(l==-1){
            l=suf[i]-pre[i-1];
            a=pre[i-1];
            b=suf[i];
        }
        else {
            if(l>suf[i]-pre[i-1]){
                l=suf[i]-pre[i-1];
                a=pre[i-1];
                b=suf[i];
            }
        }
    }
    bool ok=false;
    for(int i=1;i<=lb ;i++ ){
        if(i>a&&i<b)continue;
        printf("%c",B[i]);
        ok=true;
    }
    if(!ok)printf("-");
    printf("
");
}

参考文献

https://blog.csdn.net/fouzhe/article/details/55188502

原文地址:https://www.cnblogs.com/MalcolmMeng/p/9808389.html