区间最小覆盖 3D

div3的一道板子题,给你一个文本串,和n个匹配串,匹配串可以覆盖与自己内容相同的原串,可覆盖多次,问最小几次覆盖。

传送门

Solution

直接STL预处理串能够覆盖的区间,然后区间最小覆盖来搞。

Code

#include <bits/stdc++.h>
using namespace std;
string s, x;
int n;
struct seg
{
    int id, l, r;
    bool operator < (const seg& rhs) const
    {
        return this->l == rhs.l ? this->r < rhs.r : this->l < rhs.l;
    }
};
vector<seg> v;
signed main()
{
    ios::sync_with_stdio(false), cin.tie(0);
    int T;
    cin >> T;
    while(T-- && cin >> s)
    {
        v.clear();
        cin >> n;
        for(int i = 1; i <= n; ++i)
        {
            cin >> x;
            int len = x.size(), k = s.size() - len;
            for(int j = 0; j <= k; ++j)
            {
                if(s.substr(j, len) == x) v.push_back({i, j, j + len - 1});
            }
        }
        sort(v.begin(), v.end());
        vector<pair<int, int>> ok;
        int mxlen = s.size() - 1, L = 0, f = 0;
        for(int i = 0; i < v.size(); ++i)
        {
            int j = i, R = -1;
            int t = j;
            while(j < v.size() && v[j].l <= L)
            {
                if(v[j].r > R) R = v[j].r, t = j;
                j++;
            }
            if(R < L) break;
            L = R + 1, i = j - 1;
            ok.push_back({v[t].id, v[t].l});
            if(R >= mxlen)
            {
                f = 1;
                break;
            }
        }
        if(f)
        {
            cout << ok.size() << "\n";
            for(auto c : ok) cout << c.first << " " << c.second + 1 << "\n";
        }
        else cout << "-1\n";
    }
    return 0;
}
posted @ 2022-08-04 08:38  std&ice  阅读(46)  评论(0编辑  收藏  举报