区间最小覆盖 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;
}