Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- """
- Дан текст T и набор строк. Надо определить, представим ли Т из этих строк.
- Строка s_i может встречаться в разбиении текста T произвольное число раз.
- Можно использовать не все строки для разбиения. Строки могут идти в любом порядке.
- -- ПРИНЦИП РАБОТЫ --
- Сначала строим префиксное дерево по всем словам. После чтения слова сразу добавляем его в префиксное дерево.
- При этом помечаем вершины - концы слов (`end` = True)
- Дальше с помощью динамического программирования пытаемся уложить слова в тексте.
- - Строка dp - это булевый массив равный длине текста.
- - True - означает, что текущее слово с учетом некоторого сочетания пройденных слов заканчивается
- на текущем индексе буквы `i`.
- - Базовый случай.
- Базовый случай - это пустая строка.
- Для служебного индекса 0 мы записываем значение True
- - Порядок вычисления:
- Мы обходим текст. Если перед текущим символов закончилось какое то слова, то мы ищем
- в префиксном дереве все слова, которые могут продолжить текст дальше и помечаем окончания (индекс текста)
- таких слов равными True
- - Переход динамики:
- Переход происходит, если в текущем элементе True, что означает, что до текущего символа можно составить текст
- из какого-то сочетания слов словаря.
- - Ответ хранится в последнем элементе:
- True - значит какое-то сочетание любых слов из словаря составило текст целиком.
- -- СЛОЖНОСТЬ АЛГОРИТМА --
- Сложность создания префиксного дерева линейная и составляет O(n), где n - число всех букв во всех словах словаря.
- Потому что мы проходим каждое слово по буквам.
- Сложность поиска составляет в худшем случае O(s * n)
- Где s - длина текста.
- Мы проходим текст по букве и затем обходим в дереве подходящие слова.
- -- ПРИМЕРЫ ВВОДА И ВЫВОДА --
- examiwillpasstheexam
- 5
- will
- pass
- the
- exam
- i
- = YES
- abacaba
- 2
- abac
- caba
- = NO
- abacaba
- 3
- abac
- caba
- aba
- = YES
- bwvfbtrjqpbwvfbbwvbwbbwbbwvbwvf
- 4
- bwvf
- b
- bw
- bwv
- = NO
- """
- import sys
- class NodeTrie:
- def __init__(self):
- self.children = {}
- self.end = False
- def add_node(self, ch):
- self.children[ch] = NodeTrie()
- def add_word(trie, word):
- cur_node = trie
- for ch in word:
- if ch not in cur_node.children:
- cur_node.add_node(ch)
- cur_node = cur_node.children[ch]
- cur_node.end = True
- return trie
- def find_words(trie, text, start):
- cur_node = trie
- arr_idx = []
- for i in range(start, len(text)):
- if text[i] in cur_node.children:
- cur_node = cur_node.children[text[i]]
- if cur_node.end:
- arr_idx.append(i + 1)
- else:
- break
- return arr_idx
- def check_text(trie, text):
- dp = [True] + [False] * len(text)
- for i in range(len(dp)):
- if dp[i]:
- arr_idx = find_words(trie, text, i)
- for idx in arr_idx:
- dp[idx] = True
- return 'YES' if dp[-1] else 'NO'
- def main():
- text = input().strip()
- n = int(input())
- trie = NodeTrie()
- for i in range(n):
- word = sys.stdin.readline().strip()
- trie = add_word(trie, word)
- print(check_text(trie, text))
- if __name__ == '__main__':
- main()
Add Comment
Please, Sign In to add comment