#模拟#B 字串修改

题目

有两个字符串\(s,t\),其中\(s\)只包含小写字母以及 *,\(t\)只包含小写字母。

你可以进行任意多次操作,每次选择\(s\)中的一个 *,将它修改为任意多个(可以是0个)它的前一个字符。

请求出是否能将\(s\)修改为\(t\)。(\(T\leq 100,len\leq 3*10^4\))


分析

考虑记录\(t\)中连续的字母以及长度,考虑用\(s\)匹配,
\(s\)也是可以用一段连续的字母或星号匹配,如果当前匹配的字母不同
或者是\(s\)中的字母个数超过\(t\)中的字母个数(不能删除)
又或者是不存在星号且两段长度不相同均为无解,均不满足以上条件才有解


代码

#include <cstdio>
#include <cstring>
#define rr register
using namespace std;
const int N = 30011;
char s1[N], s2[N];
int T, tot, len1, len2, J, A[N], B[N];
signed main() {
    freopen("strinq.in", "r", stdin);
    freopen("strinq.out", "w", stdout);
    for (scanf("%d", &T); T; --T) {
        scanf("%s%s", s1 + 1, s2 + 1), tot = 0, J = 1;
        len1 = strlen(s1 + 1), len2 = strlen(s2 + 1);
        for (rr int l = 1, r = 1; l <= len2; l = ++r) {
            for (; s2[r + 1] == s2[l]; ++r)
                ;
            A[++tot] = r - l + 1, B[tot] = s2[l];
        }
        for (rr int l = 1, r = 1; l <= len1; l = ++r)
            if (s1[l] != '*') {
                rr int t = 0;
                for (; s1[r + 1] == s1[l] || s1[r + 1] == '*'; ++r)
                    ;
                for (rr int j = l; j <= r; ++j)
                    if (s1[j] != '*')
                        ++t;
                if (B[J] != s1[l] || A[J] < t)
                    break;
                else if (t == r - l + 1 && A[J] > t)
                    break;
                else
                    ++J;
            }
        if (J <= tot)
            printf("No\n");
        else
            printf("Yes\n");
    }
    return 0;
}
posted @ 2020-10-13 19:22  lemondinosaur  阅读(120)  评论(0编辑  收藏  举报