제로베이스 20220509 코테 연습
1. 팩토리얼 0의 개수
- 
    널리 잘 알려진 자료구조 중 최소 힙이 있다. 최소 힙을 이용하여 다음과 같은 연산을 지원하는 프로그램을 작성하시오. - 배열에 자연수 x를 넣는다.
- 배열에서 가장 작은 값을 출력하고, 그 값을 배열에서 제거한다.
 
- 
    프로그램은 처음에 비어있는 배열에서 시작하게 된다. 
입력
- 첫째 줄에 연산의 개수 N(1 ≤ N ≤ 100,000)이 주어진다.
- 다음 N개의 줄에는 연산에 대한 정보를 나타내는 정수 x가 주어진다.
- 만약 x가 자연수라면 배열에 x라는 값을 넣는(추가하는) 연산이고, x가 0이라면 배열에서 가장 작은 값을 출력하고 그 값을 배열에서 제거하는 경우이다.
- x는 $2^{31}$보다 작은 자연수 또는 0이고, 음의 정수는 입력으로 주어지지 않는다.
출력
- 입력에서 0이 주어진 횟수만큼 답을 출력한다. 만약 배열이 비어 있는 경우인데 가장 작은 값을 출력하라고 한 경우에는 0을 출력하면 된다.
풀이
import sys
import heapq
arr = []
for _ in range(0,int(sys.stdin.readline())):
    x = int(sys.stdin.readline())
    if x > 0:
        heapq.heappush(arr,x)
    else:
        if arr:
            print(heapq.heappop(arr))
        else:
            print(0)
채점 결과
- 정답
리뷰
- heapq에서 제공하는 기본 힙은 최소힙이므로, 활용하여 풀었다.
2. 듣보잡
- 김진영이 듣도 못한 사람의 명단과, 보도 못한 사람의 명단이 주어질 때, 듣도 보도 못한 사람의 명단을 구하는 프로그램을 작성하시오.
입력
- 첫째 줄에 듣도 못한 사람의 수 N, 보도 못한 사람의 수 M이 주어진다.
- 이어서 둘째 줄부터 N개의 줄에 걸쳐 듣도 못한 사람의 이름과, N+2째 줄부터 보도 못한 사람의 이름이 순서대로 주어진다.
- 이름은 띄어쓰기 없이 알파벳 소문자로만 이루어지며, 그 길이는 20 이하이다.
- 
    N, M은 500,000 이하의 자연수이다. 
- 듣도 못한 사람의 명단에는 중복되는 이름이 없으며, 보도 못한 사람의 명단도 마찬가지이다.
출력
- 듣보잡의 수와 그 명단을 사전순으로 출력한다.
풀이
import sys
N,M = list(map(int,sys.stdin.readline().split()))
dic = {}
arr = []
for _ in range(0,N):
    name = sys.stdin.readline().strip('\n')
    if name not in dic.keys():
        dic[name] = 0
for _ in range(0,M):
    name = sys.stdin.readline().strip('\n')
    if name in dic.keys():
        arr.append(name)
print(len(arr))
[print(x) for x in sorted(arr)]
채점 결과
- 정답
리뷰
- 
    듣도 못한 인간과 보도 못한 인간의 교집합을 구하는 문제로 생각하면 될것같다. 
- 
    듣도 못한 인간을 딕셔너리에 넣고, 보도 못한 인간이 그 안에 있으면 따로 배열에 저장한다. 
- 
    배열의 길이와 배열의 내용을 출력한다 
- 
    배열의 내용을 출력할때 시험삼아 print문을 list comprehension안에 넣어서 굴려봤는데, 기대한대로 깔끔하게 작동해줘서 만족스러웠다. 
더 나은 풀이
- 풀이 출처 : 아이디 hhs666님의 풀이
import sys
n, m = map(int, input().split())
nameList = sys.stdin.read().splitlines()
hearset = set(nameList[:n])
seeset = set(nameList[n:])
ret = list(hearset & seeset)
ret.sort()
print(len(ret))
for i in ret:
    print(i)
더 나은 풀이 해설
- 
    처음 내가 제시했던것처럼, 두 집합의 교집합을 구하는 방법을 사용했다. 
- 
    set을 통해 듣도못한/보도못한 집합의 중복을 제거한다. 
- 
    list(hearset & seeset)을 통해 중복되는 요소만 뽑아낸다. 
- 
    사전순으로 출력해야 하므로, 한번 정렬해주고 리스트의 길이와 내용을 출력해준다. 
