백준 풀이
백준 / python / 1897. 토달기
땡구리
2023. 2. 2. 12:32
https://www.acmicpc.net/problem/1897
문제 요약
다수의 문자열이 주어졌을 때 처음 주어진 문자열에서 임의의 문자를 한 글자씩 섞어서 만들 수 있는 최장 문자열을 구하시오.
풀이 요약
1. 문자열 배열을 정렬한다.
2. 문자열 배열을 순환하면서 문자열(A)에서 한 글자를 뺀 문자열이 path 배열에 있는지 확인 후 path 에 그 문자열(A)을 기록한다.
3. 그 문자열(A) 가 ans 보다 길면 ans 에 그 문자열(A)을 입력한다.
4. 문자열을 다 순환하면 ans 를 출력한다.
주의사항
brute force 로는 느리다.
for 문 자체가 있으면 아무리 skip 로직을 넣는다 해도 느리다.
만약 6개의 item 이 있다면 그냥 full scan 하는게 3/3 으로 나눠서 for 문 2개 돌면서 skip 로직 넣는 것 보다 빠르다.
예로 아래 두 코드는 각각 56ms / 332ms 이다.
from sys import stdin
input = stdin.readline
d, word = input().split()
words = []
for _ in range(int(d)):
words.append(input().rstrip())
words.sort(key=lambda x: len(x))
ans = word
path = {word: True}
for word in words:
l = len(word)
for i in range(l):
new_word = word[:i] + word[i + 1 :]
if new_word in path:
path[word] = True
if len(word) > len(ans):
ans = word
print(ans)
from sys import stdin
from collections import deque, defaultdict
input = stdin.readline
d, word = input().split()
words = defaultdict(dict)
for _ in range(int(d)):
new_word = input().rstrip()
words[len(new_word)][new_word] = False
q = deque([word])
while q:
word = q.popleft()
word_len = len(word)
try:
for next_word in words[word_len + 1]:
if words[word_len + 1][next_word]:
continue
for i in range(word_len + 1):
new_word = next_word[:i] + next_word[i + 1 :]
if word == new_word:
q.append(next_word)
words[word_len + 1][next_word] = True
break
except KeyError:
break
print(word)