D
题意
给定一个长字符串和n个短字符串,要求将n个短字符串任意顺序任意次数的拼成长字符串
样例
bababa
2
ba
aba
答案是 可以是 ba aba ba(可重叠)
思路
将每个短字符串在长字符串的出现的区间都存下来,我们就得到了一堆区间,只需要再做一个区间合并成1 ~ n 的区间并记录答案
代码实现
struct node
{
int l, r, k;
} seg[N];
bool cmp (node a, node b)
{
if (a.l != b.l)
return a.l < b.l;
else return a.r > b.r;
}
void solve()
{
string t;
cin >> t;
int m = t.size();
int n;
cin >> n;
int cnt = 0;
for (int i = 1 ; i <= n ; i ++)
{
string str;
cin >> str;
int len = str.size();
for (int j = 0; j <= m - len; j ++)
if (str == t.substr (j, len))
seg[cnt ++] = {j + 1, j + len, i};
}
sort (seg, seg + cnt, cmp);
int res = 0;
bool ok = false;
int st = 0, ed = m;
vector<PII> ans;
for (int i = 0; i < cnt; i ++)
{
int j = i, r = -2e9;
int now = -1;
while (j < cnt and seg[j].l <= st + 1)
{
if (r < seg[j].r)
{
r = seg[j].r ;
now = j;
}
j ++;
}
if (r < st)
{
res = -1;
break;
}
res ++;
if (r >= ed)
{
ok = true;
if (now != -1) ans.push_back ({seg[now].k, seg[now].l});
break;
}
if (now != -1) ans.push_back ({seg[now].k, seg[now].l});
st = r;
i = j - 1;
}
if (!ok)
{
cout << -1 << '\n';
return ;
}
cout << res << '\n';
for (int i = 0; i < ans.size(); i ++)
cout << ans[i].x << ' ' << ans[i].y << '\n';
for (int i = 0; i < cnt ; i ++)
seg[i].l = seg[i].r = seg[i].k = 0;
}
E
题意
给定一个序列,对于序列的每个数可以进行的操作 加上这个数mod10的值
问经过任意次数后序列的所有数能不能相等
思路
可以发现对于某个数来说它进行了足够多次这个操作,所得到的数 mod 20 的数是一个循环序列,而且只能分成两个组,我们只需预处理这两组数然后判断整个序列里的数mod 20 后是不是都在一个组即可
注意特判 5 只能变成 10 也就是个位为5的数只能向上 + 5, 个位为0 的数不能改变
代码实现
unordered_set<int> S =
{
2, 4, 8, 16
};
void solve()
{
int n;
cin >> n;
PII sp = {-1, 0}; bool check = true;
for (int i = 1 ; i <= n ; i ++)
cin >> a[i];
// 特判 5 和 10
for (int i = 1 ; i <= n ; i ++)
if (a[i] % 10 == 5 or a[i] % 10 == 0)
{
if (sp.x == -1) sp.x = (a[i] + 5) / 10, sp.y = 1;
else if (sp.x == (a[i] + 5) / 10) sp.y ++;
}
// 将所有奇数变成偶数在mod 20(因为只预处理了偶数集合)
for (int i = 1 ; i <= n ; i ++)
{
if (a[i] & 1) a[i] = a[i] + a[i] % 10;
a[i] %= 20;
}
if (sp.x != -1)
{
if (sp.y == n)
cout << "Yes\n";
else cout << "No\n";
return ;
}
bool isin = S.count (a[1]);
for (int i = 2 ; i <= n ; i ++)
if (isin != S.count (a[i]))
{
cout << "No\n";
return ;
}
cout << "Yes\n";
}