본문 바로가기

알고리즘 공부/알고리즘 구현 기초

백준) 과제 안 내신분...?-파이썬

https://www.acmicpc.net/problem/5597

(브론즈 5 문제)

 

5597번: 과제 안 내신 분..?

X대학 M교수님은 프로그래밍 수업을 맡고 있다. 교실엔 학생이 30명이 있는데, 학생 명부엔 각 학생별로 1번부터 30번까지 출석번호가 붙어 있다. 교수님이 내준 특별과제를 28명이 제출했는데,

www.acmicpc.net

입력

1.

3
1
4
5
7
9
6
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30

2.

9
30
6
12
10
20
21
11
7
5
28
4
18
29
17
19
27
13
16
26
14
23
22
15
3
1
24
25

출력

1.

2
8

2.

2
8

내 코드

student=[i+1 for i in range(30)]
result=[None]*30
for i in range(28):
    n=int(input())
    result[i]=n
set1=set(student)
set2=set(result)
result_set=set1-set2
print(min(result_set))
print(max(result_set))

풀이(생각 과정)

처음에 학생이 30명이 존재한다고 해서 1번 학생부터 30번 학생까지의 번호를 저장한 student 리스트를 만들었다.

그 후 값들을 받아서 만들 result 리스트를 None 값을 30개 넣어서 초기화 해놨다.

 

반복문을 통해서 28명의 학생의 출석 번호를 받고, 그 받은 값을 result 리스트에 대입하였다.

 

2개의 값을 비교하기 위해서 차집합을 이용했다. 차집합을 활용하기 위해서는 student 리스트와 result 리스트를 집합으로 변환시킬 필요가 있었기에 내장 함수 set을 이용해서 set1과 set2 집합으로 변환시켰다. 그 후 차집합한 집합을 result_set이라 정의하였다.

 

그 후 result_set 내에 최솟값을 먼저 출력하고 그 다음 최댓값을 출력하는 형식으로 구현하였다.

개선된 다른 풀이

l = []
for i in range(30):
    l.append(i+1)

for _ in range(28):
    n = int(input())
    l.remove(n)
    
print(min(l))
print(max(l))

1번째 반복문의 경우 개선점이라 보긴 힘들었다. 단순히 1부터 30까지 리스트를 만드는 과정은 동일했다. l이라는 이름으로 구현했다.

 

2번째 반복문에서 차이가 났는데 1부터 30번까지 넣은 리스트에서 입력한 값을 제거하는 remove 함수를 이용해서 구현하였다. 이렇게 구현한다면 result라는 리스트를 만들 필요 없이 바로바로 값이 제거 되서 결국 l 리스트에는 제출하지 않은 학생의 출석 번호만 남게 된다.

 

출력 역시 동일하게 출력하였다.

풀이의 차이점 및 반성할 점

내 방식의 경우 집합으로 바꿔서 계산하는 불필요한 과정이 들어갔다. 그렇기에 result라는 리스트를 따로 생성했고, 메모리 낭비로 이어지게 되었다.

이는 파이썬의 내장 함수인 remove의 존재를 몰랐던 것이랑 함께 전체 리스트에서 제거하는 방식을 생각하지 못하고 2개의 리스트를 만들어서 비교하겠다라는 생각의 차이가 이런 결과를 만들어냈다. 

 

물론 내가 작성한 코드가 잘못되었다 이런 것은 아니지만 아무래도 문제의 조건을 보고 더 효율적으로 짜는 사고 방식을 길러야겠다고 느껴서 글을 남긴다.