Problem Solving/boj
[BOJ]1593. 문자 해독(Python) / Sliding Window
chesleashin
2021. 5. 5. 19:28
1593번: 문자 해독
첫째 줄에 고고학자들이 찾고자 하는 단어 W의 길이 g와 발굴된 벽화에서 추출한 문자열 S의 길이 |S|가 빈 칸을 사이에 두고 주어진다. (1≤g≤3000, g≤|S|≤3,000,000) 둘째 줄에 W, 셋째 줄에 S의 실
www.acmicpc.net
W를 이루고 있는 g개의 그림문자와, 연구 대상인 벽화에 기록된 마야 문자열 S가 주어졌을 때, 단어 W가 마야 문자열 S에 들어있을 수 있는 모든 가짓수를 계산하는 프로그램을 작성하시오. 즉, 문자열 S안에서 문자열 W의 순열 중 하나가 부분 문자열로 들어있는 모든 경우의 수를 계산하라는 뜻이다.
- 사용 알고리즘 : Sliding Window
- 처음에 순열 구하는 코드로 접근했으나 시간초과로 틀리는 것을 보고, 슬라이딩 윈도우 방식으로 접근해야한다는 것을 깨달았다.
- 슬라이딩 윈도우 방식에 아직 익숙하지 않아 다른 분의 코드를 참고했다. 설명을 잘 해놓으셨으니 참고 바란다.
- 참고 링크는 hongcoding.tistory.com/64
파이썬 코드는 다음과 같다.
from sys import stdin
input = stdin.readline
# main
wlen, slen = map(int, input().split())
w = input().strip()
s = input().strip()
wInfo = [0] * 52
sInfo = [0] * 52
for i in range(wlen):
if 'a' <= w[i] <= 'z':
wInfo[ord(w[i]) - ord('a')] += 1 # 소문자 처리
else:
wInfo[ord(w[i]) - ord('A') + 26] += 1 # 대문자 처리
start, length, result = 0, 0, 0
for i in range(slen):
if 'a' <= s[i] <= 'z':
sInfo[ord(s[i]) - ord('a')] += 1
else:
sInfo[ord(s[i]) - ord('A') + 26] += 1
length += 1 # 길이 1칸 늘리기.
# Sliding Window
if length == wlen: # 탐색 길이와 찾을 문자열 길이가 같으면
if wInfo == sInfo: # 찾는 문자열과 구성 일치
result += 1
if 'a' <= s[start] <= 'z':
sInfo[ord(s[start]) - ord('a')] -= 1
else:
sInfo[ord(s[start]) - ord('A') + 26] -= 1
start += 1 # 시작 위치 1칸 밀고
length -= 1 # 길이는 1칸 줄여준다.
print(result)
- 시간 : 508ms / 메모리 : 133560kb
- 고찰 : 문자열 문제를 순열(재귀 또는 itertools 라이브러리)을 사용하지 않고 슬라이딩 윈도우 방식으로 푸니까 시간초과 나지 않고 풀어낼 수 있다는 것을 알았다. 이번 네이버 코딩테스트도 이와 유사한 문제가 나왔는데, 시간초과로 터졌으리라 본다ㅠㅠ 아쉽다. 이렇게 하나 배웠으니 다음엔 절대 틀리지 말자.