Codeforces - 1203D2 (思维)

本文详细解析了Codeforces-1203D2题目,探讨了如何寻找字符串s1中能被连续删除的最长区间,使s2仍为s1的非连续子串。通过确定s2在s1中的最左和最右匹配点,以及s1中可删除的最大间隔,提供了一种简洁有效的解决方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Codeforces - 1203D2 (思维)

题目链接:http://codeforces.com/problemset/problem/1203/D2

题目大意:给出一段长串s1和它的一段非连续子串s2,求s1最长的连续删除区间,使得s2仍为s1的非连续子串

分析:最大分割情况只可能是两种,一种是最左端或者最右端删去一大段,另一种是中间任意两个字母间删去一大段

先看第一种,那么肯定是要找到s2在s1中的最左相同点和最右相同点,很简单

另一种,删去的区间端点两个字母肯定是s2中相邻的字母,即保证删去中间一段没用的,仍是子串 例如s1:abbccbbbcccddde s2: ab
那么最长区间肯定是找到s1最左端满足条件的a,再找到s1最右端满足条件的b,中间都是可以删的,如果s2:abd 就找到s1最左端满足条件的b,再找到s1最右端满足条件的d,作差值,然后取max

挺有趣的一道题。列为有趣的cf题,当时是真写不出来,看题解居然这么简单,一直想到序列自动机去了,还真是想多了

 

代码:

#include <bits/stdc++.h>

using namespace std;

char a[200005];
char b[200005];
int from[200005];
int to[200005];

int main()
{
    cin >> a >> b;
    int len = strlen(a);
    int len2 = strlen(b);
    int i,j;
    j = 0;
    for ( i=0; i<len; i++ ) { // 从前往后找
        if ( j==len2 ) {
            break ;
        }
        if ( a[i]==b[j] ) {
            from[j] = i;
            j ++;
        }
    }
    j = len2-1;
    for ( i=len-1; i>=0; i-- ) { // 从后往前找
        if ( j==-1 ) {
            break ;
        }
        if ( a[i]==b[j] ) {
            to[j] = i;
            j --;
        }
    }
    int ans = 0;
    ans = max( max(from[0],to[0]),ans ); // 取左边界无用部分
    ans = max( len-1-min(from[len2-1],to[len2-1]),ans ); // 取右边界无用部分
    for ( i=1; i<len; i++ ) {
        ans = max(ans,to[i]-from[i-1]-1); // 好好理解这个部分
    }
    cout << ans << endl;

    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值