Codeforces Round #704 (Div. 2)-C. Maximum width-题解

49 阅读2分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

@TOC

Codeforces Round #704 (Div. 2)-C. Maximum width

传送门 Time Limit: 2 seconds Memory Limit: 512 megabytes

Problem Description

Your classmate, whom you do not like because he is boring, but whom you respect for his intellect, has two strings: ss of length nn and tt of length mm.

A sequence p1,p2,,pmp_1, p_2, \ldots, p_m, where 1p1<p2<<pmn1 \leq p_1 < p_2 < \ldots < p_m \leq n, is called beautiful, if spi=tis_{p_i} = t_i for all ii from 11 to mm. The width of a sequence is defined as max1i<m(pi+1pi)\max\limits_{1 \le i < m} \left(p_{i + 1} - p_i\right).

Please help your classmate to identify the beautiful sequence with the maximum width. Your classmate promised you that for the given strings ss and tt there is at least one beautiful sequence.

Input

The first input line contains two integers nn and mm (2mn21052 \leq m \leq n \leq 2 \cdot 10^5) — the lengths of the strings ss and tt.

The following line contains a single string ss of length nn, consisting of lowercase letters of the Latin alphabet.

The last line contains a single string tt of length mm, consisting of lowercase letters of the Latin alphabet.

It is guaranteed that there is at least one beautiful sequence for the given strings.

Output

Output one integer — the maximum width of a beautiful sequence.

Sample Input

5 3
abbbc
abc

Sample Onput

3

Note

In the first example there are two beautiful sequences of width 33: they are {1,2,5}\{1, 2, 5\} and {1,4,5}\{1, 4, 5\}.

In the second example the beautiful sequence with the maximum width is {1,5}\{1, 5\}.

In the third example there is exactly one beautiful sequence — it is {1,2,3,4,5}\{1, 2, 3, 4, 5\}.

In the fourth example there is exactly one beautiful sequence — it is {1,2}\{1, 2\}.


题目大意

两个字符串s和t长度分别是n和m。 在s从左到右选一些字母组成t。 问s中所有选中的字符中,最大间距是多少。

题目保证能从s中选出t。


题目分析

要使间距最大,就要t中的某两个相邻的字母在s中选择时,第一个字母尽可能往前,第二个字母尽可能往后,这样才能使间距最大。

如s(abbbc)中选择t(abc),看t中相邻两个字母,先看aba要选的尽可能靠前(其实就一种选择),所以选第1个。b要选的尽可能靠后(可以选第2~4个),所以选第4个。这样的话它的最大间距就是4-3=3。同理看bc时,应分别选择第2个和第5个,间距同样是5-2=3。所以最大间距是3


解题思路

先从前往后遍历一遍,得到t中每个字母最靠前能选到s的第几个; 再从后往前遍历一遍,得到t中每个字母最靠后能选到s的第几个。 考虑所有t中相邻的两个字母,看看第一个字母最靠前,第二个字母最靠后,间距是多少。 更新最大间距,直到遍历完t。


AC代码

#include <bits/stdc++.h>
using namespace std;
#define mem(a) memset(a, 0, sizeof(a))
#define dbg(x) cout << #x << " = " << x << endl
#define fi(i, l, r) for (int i = l; i < r; i++)
#define cd(a) scanf("%d", &a)
typedef long long ll;
char s[200010];
char t[200010];
int zuiQian[200010]; //最靠前能选到s中的第几个
int zuiHou[200010]; //最靠后能选到s中的第几个
int main()
{
    int n, m, M = 1;
    scanf("%d%d", &n, &m);
    scanf("%s", s);
    scanf("%s", t);
    int lastT = -1;
    for (int i = 0; i < m; i++)
    {
        while (s[++lastT] != t[i]) //找到s中第一个没有选过的并且与t的下一个相同的字母。
            ;
        zuiQian[i] = lastT;
    }
    lastT = n;
    for (int i = m - 1; i >= 0; i--)
    {
        while (s[--lastT] != t[i])
            ;
        zuiHou[i] = lastT;
    }
    for (int i = 1; i < m; i++)
    {
        M = max(M, zuiHou[i] - zuiQian[i - 1]); //更新最大值
    }
    printf("%d\n", M);
    return 0;
}

注意事项

while (s[++lastT] != t[i]);是打比赛时确定s中下一个位置的简便写法。

学会的话打比赛会快亿点点,但是小心不要用错了哦。

同步发文于我的CSDN