[ABC329E] Stamp
update on
Description
有两个字符串 # 构成的字符串
现在可以执行若干次操作,每次可以选择字符串
求:是否能通过若干次操作,使得
Solution
考虑一个覆盖时间的序列(钦定每一次覆盖记录在其右端点上),发现对于当前点
只有
优化点,即当前状态包含当前位置 <p,st> 这样一个状态,那当前就没必要继续往下搜了。
Code
#include <bits/stdc++.h>
using namespace std;
unordered_map<int, int> mp;
int n, m;
int gethash(int now, int stat[5]) {
int hsh = now;
for (int i = 0; i < m - 1; i++) hsh = hsh * m + stat[i];
return hsh;
}
char s[200055];
char t[55];
bool search(int now, int stat[5]) {
int hsh = gethash(now, stat);
if (mp.find(hsh) != mp.end()) return false;
mp[hsh] = 1;
if (now == n + 1) {
char x[6];
for (int j = 1; j < m; j++) {
for (int k = 0; k < m - 1; k++) {
if (stat[k] == j) {
for (int l = 2; l <= m - k; l++) {
x[l] = t[l + k];
}
}
}
}
for (int i = 2; i <= m; i++) if (s[n + i - m] != x[i]) return false;
return true;
}
for (int i = 1; i <= m; i++) {
int new_stat[5];
new_stat[0] = i;
for (int j = 1; j < m; j++) {
new_stat[j] = stat[j - 1];
if (stat[j - 1] >= i) ++new_stat[j];
}
bool flag = true;
for (int j = 0; j < m; j++) {
if (new_stat[j] == m) {
if (s[now - m + 1] != t[j + 1]) flag = false;
}
}
if (!flag) continue;
for (int j = 0; j < m - 1; j++) {
if (new_stat[j] > new_stat[m - 1]) --new_stat[j];
}
if (search(now + 1, new_stat)) return true;
}
return false;
}
int stat[5];
int main() {
cin >> n >> m;
scanf("%s%s", s + 1, t + 1);
if (s[1] != t[1]) {
puts("No");
return 0;
}
for (int i = 0; i < 5; i++) stat[i] = m - i - 1;
if (search(m + 1, stat)) {
printf("Yes");
return 0;
}
printf("No");
return 0;
}