CF1476E. Pattern Matching
CF1476E Pattern Matching
描述
有 n 个模式串 p[n],m 个字符串 s[n] 和对应的数字 \(mk_i\) ,每个模式串和字符串包含 k 个字符,(包含正常字符和下划线,其中下划线能匹配任意字符),要求模式串的一个排列使得,第 i 个字符串第一个匹配到的模式串为 \(p[mk_i]\)
思路
首先预处理所有字符串能匹配的模式串,即将对应的字符转化为下划线,找出其在模式串中的位置,如果位置中不包含 \(mk_i\),显然不能找到,否则用拓扑排序的方式将 mk 连边到所有除 mk 之外的下标,输出拓扑序即可。
代码
#include <bits/stdc++.h>
using namespace std;
int main() {
int n, m, k;
queue<int> q;
scanf("%d%d%d", &n, &m, &k);
map<string, int> mp;
vector<vector<int>> adj(n);
vector<int> ind(n, 0);
for (int i = 0; i < n; i++) {
string str;
cin >> str;
mp[str] = i;
}
bool ck = false;
for (int i = 0; i < m; i++) {
string str;
cin >> str;
int mk;
cin >> mk;
mk--;
bool flag = false;
if (ck) continue;
for (int j = 0; j < (1 << k); j++) {
string tmp = str;
for (int x = 0; x < k; x++)
if ((j >> x) & 1) tmp[x] = '_';
if (mp.count(tmp))
if (mp[tmp] == mk)
flag = true;
else {
adj[mk].push_back(mp[tmp]);
ind[mp[tmp]]++;
}
}
if (!flag) ck = true;
}
if (ck)
puts("NO");
else {
vector<int> res;
for (int i = 0; i < n; i++)
if (!ind[i]) q.push(i);
while (q.size()) {
int u = q.front();
q.pop();
res.push_back(u);
for (int v : adj[u]) {
ind[v]--;
if (!ind[v]) {
q.push(v);
}
}
}
if (res.size() == n) {
puts("YES");
for (int it : res) cout << it + 1 << " ";
} else {
puts("NO");
}
}
return 0;
}

浙公网安备 33010602011771号