• [CF762C] Two strings


    [CF762C] Two strings - 双指针

    Description

    给定 (2) 仅包含小写字母字符串 (s)(t),从 (s) 中删除连续的一段字符,使得 (s)(t) 的子序列。最小化删除的数量,并输出执行删除操作后的字符串 (s)

    Solution

    预处理 (s) 的每个前缀在 (t) 中从头开始做子序列匹配到的位置,(s) 的每个后缀在 (t) 中从尾反向开始做子序列匹配到的位置,然后双指针处理即可

    #include <bits/stdc++.h>
    using namespace std;
    
    #define int long long
    
    const int N = 1e6 + 5;
    
    char s[N], t[N];
    int a[N], b[N], n, m;
    
    signed main()
    {
        ios::sync_with_stdio(false);
    
        cin >> t + 1 >> s + 1;
        n = strlen(s + 1);
        m = strlen(t + 1);
    
        for (int i = 1; i <= n; i++)
        {
            int j;
            for (j = a[i - 1] + 1; j <= m; j++)
                if (s[i] == t[j])
                    break;
            if (j <= m)
                a[i] = j;
            else
                a[i] = m + 1;
        }
    
        b[n + 1] = m + 1;
        for (int i = n; i >= 1; i--)
        {
            int j;
            for (j = b[i + 1] - 1; j >= 1; j--)
                if (s[i] == t[j])
                    break;
            if (j >= 1)
                b[i] = j;
            else
                b[i] = 0;
        }
    
        int ans = 0, ansx, ansy;
        for (int i = 1, j = 2; i <= n; i++)
        {
            if (i >= j)
                j = i + 1;
            while (a[i] >= b[j])
                j++;
            if (i + n - j + 1 > ans)
            {
                ans = i + n - j + 1;
                ansx = i;
                ansy = j;
            }
        }
    
        for (int i = 1; i <= n; i++)
        {
            if (a[i] <= m && i > ans)
            {
                ans = i;
                ansx = i;
                ansy = n + 1;
            }
        }
    
        for (int i = 1; i <= n; i++)
        {
            if (b[i] >= 1 && n - i + 1 > ans)
            {
                ans = n - i + 1;
                ansx = 0;
                ansy = i;
            }
        }
    
        // for (int i = 1; i <= n; i++)
        //     cout << a[i] << " ";
        // cout << endl;
        // for (int i = 1; i <= n; i++)
        //     cout << b[i] << " ";
        // cout << endl;
    
        if (ans == 0)
        {
            cout << "-" << endl;
        }
        else
        {
            for (int i = 1; i <= ansx; i++)
                cout << s[i];
            for (int j = ansy; j <= n; j++)
                cout << s[j];
            cout << endl;
        }
    }
    
  • 相关阅读:
    ObjectArx的一次常用方法
    GDI+ 简介(1)
    VC++获取可执行文件当前目录
    SQL Server 常用的时间处理函数
    利于Wininet创建一个FTP客户端的步骤
    Win32 文件操作的几个API
    ObjectARX中三维多段线转二维多段线的方法
    fas文件格式解析
    [转载]swf文件格式解析(一)
    [转载]swf文件格式解析(二)
  • 原文地址:https://www.cnblogs.com/mollnn/p/14647931.html
Copyright © 2020-2023  润新知