반응형
https://www.acmicpc.net/problem/12891
12891번: DNA 비밀번호
평소에 문자열을 가지고 노는 것을 좋아하는 민호는 DNA 문자열을 알게 되었다. DNA 문자열은 모든 문자열에 등장하는 문자가 {‘A’, ‘C’, ‘G’, ‘T’} 인 문자열을 말한다. 예를 들어 “ACKA”
www.acmicpc.net


내 답안
import sys input = sys.stdin.readline S, P = map(int, input().split()) DNA = input().rstrip() DNA_dict = {'A': 0, 'C': 1, 'G': 2, 'T': 3} ACGT = list(map(int, input().split())) result = 0 start_index = 0 end_index = P - 1 check_list = [0, 0, 0, 0] for i, j in enumerate('ACGT'): check_list[i] = DNA[start_index: end_index + 1].count(j) while S > end_index: start_index += 1 end_index += 1 if (ACGT[0] <= check_list[0] and ACGT[1] <= check_list[1] and ACGT[2] <= check_list[2] and ACGT[3] <= check_list[3]): result += 1 check_list[DNA_dict[DNA[start_index - 1]]] -= 1 try: check_list[DNA_dict[DNA[end_index]]] += 1 except: continue print(result)
Review
결론은 시간 복잡도 이슈로 인해 투포인터 방식으로 문제를 풀었다.
핵심은 check_list 를 만들어서 주어진 최소개수를 만족하는가에 초점을 두었다.
간단하게 나타낸다면 아래 사진 처럼 나타 낼 수 있다.

예제 입력으로 그림을 그려 설명을 하자면
# 예제 입력 2
4 2
GATA
1 0 0 1

* 코드에 예외 처리를 한 이유는 마지막 연산에서 Out-Of-Index 에러를 방지하기 위해서 예외를 하였다.

처음에는 O(N^2) 으로 코드를 짰었다.
코드가 N^2 인것만 확인 하자!
# 시간초과 코드 import sys input = sys.stdin.readline S, P = map(int,input().split()) DNA = input().rstrip() ACGT = list(map(int, input().split())) result = 0 start_index = 0 end_index = P-1 while S-1 >= end_index: check_list = [0, 0, 0, 0] for i in range(start_index, end_index + 1): if DNA[i] == 'A': check_list[0] += 1 elif DNA[i] == 'C': check_list[1] += 1 elif DNA[i] == 'G': check_list[2] += 1 elif DNA[i] == 'T': check_list[3] += 1 if (ACGT[0] <= check_list[0] and ACGT[1] <= check_list[1] and ACGT[2] <= check_list[2] and ACGT[3] <= check_list[3]): result += 1 start_index += 1 end_index += 1 print(result)

반응형
'BOJ > Python' 카테고리의 다른 글
백준 11725번 트리의 부모 찾기 파이썬 (0) | 2023.06.16 |
---|---|
백준 11003번 최솟값 찾기 파이썬 (0) | 2023.02.17 |
백준 25305번 커트라인 파이썬 (0) | 2023.01.19 |
백준 10814번 나이순 정렬 파이썬 (0) | 2023.01.18 |
백준 1316번 그룹 단어 체커 파이썬 (0) | 2022.12.04 |