데이터 엔지니어
백준 - [Platinum 3] 5446번 용량 부족 본문
문제링크: https://www.acmicpc.net/problem/5446
5446번: 용량 부족
팀포2 덕후 연수는 팀포2를 다운받던 도중 하드 용량이 부족하다는 것을 알았다. 이때는 침착하게 팀포2를 하지 말거나 하드를 새로 사면 되지만 불가능했고, 결국 하드에서 쓸모없는 파일을 지�
www.acmicpc.net
문제 설명
- N1: 지워야 할 파일의 개수
- N1개의 파일명이 주어짐
- N2: 지우지 말아야 할 파일의 개수
- N2개의 파일명이 주어짐
rm * 명령어로 전체 삭제도 가능합니다. rm a*이면 a로 시작하는 파일명들을 전부 삭제하는 명령어입니다.
지워야하는 파일만 지우게 할 수 있는 최소의 명령어 개수를 구하는 문제입니다.
ex)
N1=4 N2=1
N1: BAP, BAPC.in, BAPC.out, BAPC.tex
N2: BAPC
이면 rm BAP*를 하면 BAPC도 지워지므로 안됩니다.
rm BAP 와 rm BAPC.* 명령어 2개의 명령어가 최소의 개수입니다.
풀이
Trie 자료구조를 활용한 문제입니다.
트라이는 위의 사진과 같이 각 캐릭터를 하나의 노드에 두어 중복된 문자열을 최소화하며 트리구조로 만들어 나가는 자료구조입니다.
이 문제에서는 어떻게 활용해야 하는지 설명드리겠습니다.
1. 지워야 할 파일들을 trie로 만들어 줍니다.
2. 지우지 말아야 할 파일들을 trie 내에서 삭제하지 말라는 marking을 해줍니다. (mark = 1)
3. 지워야 할 파일들을 루프를 돌며 삭제 가능한지 판단합니다. 여기서 중요한 점이 있습니다.
- rm BAPC.* 으로 삭제를 했을경우 BAPC.in BAPC.out를 한 명령어로 처리해주어야 합니다.
- 그래서 '.'인 지점에 mark를 2로 변경하여 BAPC.out파일명이 왔을때 바로 리턴하도록 해주어야 합니다.
주의할 점
- mark나 remove할 때 꼭 끝 지점도 체크를 해주어야 합니다.
- N2가 0일때를 따로 처리해 주어야 합니다.
위의 사항들만 고려하면 풀 수 있는 문제였습니다. 저도 Trie문제를 처음 풀어봐서 하루 넘게 끙끙 댄 문제입니다.
풀이 참조: ggodong.tistory.com/168
코드
class Node(object):
def __init__(self, key, mark=0, data=None):
self.key = key
self.mark = mark
self.data = data # leaf node는 전체 string, 나머지 node들은 None을 담고 있다.
self.children = {}
class Trie(object):
def __init__(self):
self.head = Node(None)
def insert(self, string):
cur = self.head
for char in string: # 각 캐릭터 순회
# 해당 캐릭터가 트리에 없을경우 하위 노드로 추가
if char not in cur.children:
cur.children[char] = Node(char)
cur = cur.children[char] # 현재 노드 변경
# 마지막 노드의 경우 data를 스트링으로 변경하여 마지막 노드임을 명시
cur.data = string
def marking(self, string):
# insert 과정과 유사하나 삭제하지 말아야 하는 부분에 mark를 1로 설정한다.
cur = self.head
for char in string:
cur.mark = 1
if char not in cur.children:
cur.children[char] = Node(char)
cur = cur.children[char]
cur.mark = 1
def remove(self, string):
cur = self.head
result = 0
for char in string:
# 해당 캐릭터가 있고 해당 캐릭터가 mark가 되어있으면 계속 순회
if char in cur.children and cur.children[char].mark == 1:
cur = cur.children[char]
# 이미 삭제한 부분이면 종료해도 된다. 상위 명령어로 전부 삭제 가능하기 때문이다.
elif cur.children[char].mark == 2:
return result
# 삭제가능한 경우 mark를 2로 바꿔주고 return 해준다.
else:
result += 1
cur.children[char].mark = 2
# print(cur.children[char].key)
return result
result += 1
return result
from sys import stdin
stdin = open("input.txt", "r")
# T: 테스트 케이스 개수
T = int(stdin.readline())
for t in range(T):
trie = Trie()
# N1: 지워야 하는 파일 개수
N1 = int(stdin.readline())
remove_list = []
for _ in range(N1):
remove_list.append(stdin.readline().strip())
trie.insert(remove_list[-1])
# N2: 지우지 말아야 하는 파일 개수
N2 = int(stdin.readline())
for _ in range(N2):
trie.marking(stdin.readline().strip())
# 지우는 과정
answer = 0
for i in range(N1):
temp = trie.remove(remove_list[i])
# print(remove_list[i], temp)
answer += temp
# 출력
if N2 == 0: print(1)
else: print(answer)
'프로그래밍(Programming) > 알고리즘(Algorithm)' 카테고리의 다른 글
프로그래머스 - [LEVEL 2] 큰 수 만들기 (0) | 2020.09.26 |
---|---|
프로그래머스 - [LEVEL 2] 기능개발 (0) | 2020.09.24 |
백준 - [Silver 3] 2579번 계단 오르기 (0) | 2020.09.22 |
백준 - [Gold 4] 전화번호 목록 (0) | 2020.09.21 |
백준 - [Gold 2] 12100번 2048(Easy) (0) | 2020.09.20 |