Пары шаблонов Язык Версия Время Память Все языки —...
Creato il: 15 aprile 2026
Risposto usando GPT-5.4 Thinking da Chat01
Creato il: 15 aprile 2026
Risposto usando GPT-5.4 Thinking da Chat01
Пары шаблонов
Язык
Версия
Время
Память
Все языки
—
1 с
256.0 Мб
Ввод
стандартный ввод или input.txt
Вывод
стандартный вывод или output.txt
Назовем шаблоном строку, состоящую из маленьких английских букв и вопросительных знаков (?). Слово соответствует шаблону, если можно заменить вопросительные знаки в шаблоне на буквы таким образом, чтобы получилось слово. Например, слово "baca" соответствует шаблону "bac?" и "b??a", но не соответствует шаблону "?b??".
Вам дано
n
n шаблонов одинаковой длины
m
m. Необходимо определить количество пар шаблонов
(
i
,
j
)
(i,j) из этого набора, таких, что существует хотя бы одно слово, соответствующее обоим шаблонам и
1
≤
i
<
j
≤
n
1≤i<j≤n.
Формат ввода
В первой строке записаны числа
n
n (
1
≤
n
≤
50
000
1≤n≤50000) и
m
m (
1
≤
m
≤
6
1≤m≤6) — количество шаблонов и их длина соответственно.
В следующих
n
n строках записаны шаблоны. Каждый шаблон состоит из маленьких английских букв и вопросительных знаков и имеет длину
m
m.
Формат вывода
Выведите одно число — количество пар шаблонов, для которых найдется слово, соответствующее обоим шаблонам.
Пример 1
Ввод
3 3
??b
c??
c?c
Вывод
2
Пример 2
Ввод
4 6
ab??c?
??kll?
a?k??c
?bcd??
Вывод
3
Пример 3
Ввод
5 2
??
b?
c?
?g
cg
Вывод
8
реши брат быстро
Вот быстрое и нормальное решение на C++17.
У шаблона есть:
Два шаблона совместимы тогда и только тогда, когда
на всех позициях, где у обоих стоят буквы, буквы совпадают.
Так как m ≤ 6, всего масок максимум 2^6 = 64.
Сгруппируем все шаблоны по маске.
A и BПусть I = A & B — позиции, где оба шаблона имеют буквы.
Тогда шаблоны из этих групп совместимы только если их буквы на позициях I совпадают.
Значит:
B считаем, сколько шаблонов дают каждый возможный проектированный код на IA смотрим, сколько в B имеют тот же проектированный кодЕсли маска одна и та же, то совместимы только полностью одинаковые шаблоны.
То есть для каждого одинакового code добавляем cnt * (cnt - 1) / 2.
cpp#include <bits/stdc++.h> using namespace std; int main() { ios::sync_with_stdio(false); cin.tie(nullptr); int n, m; cin >> n >> m; int MASKS = 1 << m; // freq[mask][code] = сколько раз встретился такой шаблон vector<unordered_map<int, int>> freq(MASKS); for (int k = 0; k < n; ++k) { string s; cin >> s; int mask = 0; int code = 0; for (int i = 0; i < m; ++i) { if (s[i] != '?') { mask |= (1 << i); code |= ((s[i] - 'a') << (5 * i)); // 5 бит хватает на 26 букв } } freq[mask][code]++; } // Удобнее и быстрее итерироваться по vector<pair<...>> vector<vector<pair<int, int>>> groups(MASKS); for (int mask = 0; mask < MASKS; ++mask) { groups[mask].reserve(freq[mask].size()); for (auto &it : freq[mask]) { groups[mask].push_back(it); } } auto project = [&](int code, int interMask) -> int { // сжимаем буквы только на позициях interMask в компактный код int res = 0; int shift = 0; for (int i = 0; i < m; ++i) { if (interMask & (1 << i)) { int letter = (code >> (5 * i)) & 31; res |= (letter << shift); shift += 5; } } return res; }; long long ans = 0; for (int A = 0; A < MASKS; ++A) { // пары внутри одной группы: // совместимы только полностью одинаковые шаблоны for (auto &[code, cnt] : groups[A]) { ans += 1LL * cnt * (cnt - 1) / 2; } // пары между разными группами for (int B = A + 1; B < MASKS; ++B) { int I = A & B; unordered_map<int, int> cntB; cntB.reserve(groups[B].size() * 2 + 1); for (auto &[code, cnt] : groups[B]) { cntB[project(code, I)] += cnt; } for (auto &[code, cnt] : groups[A]) { auto it = cntB.find(project(code, I)); if (it != cntB.end()) { ans += 1LL * cnt * it->second; } } } } cout << ans << '\n'; return 0; }
Для двух шаблонов важно только одно:
Если маски фиксированных позиций равны A и B, то проверять надо только пересечение A & B.
На остальных позициях один из шаблонов имеет ?, значит конфликта быть не может.
≤ 64≤ 50000Итоговая сложность примерно:
O(64² · K · m), где K — среднее число различных шаблонов в группе.
При m ≤ 6 это спокойно проходит.
Если хочешь, я могу ещё сразу скинуть более короткую версию без комментариев, чисто для сдачи.