티스토리 뷰

 

요즘 매일 최소 한 문제는 푼다는 생각으로 백준에 있는 문제를 난도순으로 풀어보고 있다. 

사실 매일 한 문제씩 푸는 시도는 방송대 입학하고 첫 1~2학기쯤에 C/Cpp을 처음 배우면서 벌써 해봤는데, 그땐 주제도 모르고 처음부터 구현 같은 거 해보려고 덤비다가 하루만에 그만뒀었다. 원래 하룻고양이(?)들이 뭐 무서운 줄 모른다고. 

그러고 나서 리트코드나 백준 같은 사이트는 말만 들어도 무섭다고 도망다녔는데, 브론즈 레벨 문제로나마 점수를 채워서 실버 레벨에 겨우 도달하니 감회가 새롭다.

 

이게 중요한 게 아니고 다시 본론으로 돌아가자면 어쨌든 알고리즘 공부를 하고 있는데… 어제 백준 2789번을 풀다가 너무 어이없고 웃기는 일을 겪어서 근황 알림 겸 써본다. 

백준 2789: 블랙잭 https://www.acmicpc.net/problem/2798

 

2798번: 블랙잭

첫째 줄에 카드의 개수 N(3 ≤ N ≤ 100)과 M(10 ≤ M ≤ 300,000)이 주어진다. 둘째 줄에는 카드에 쓰여 있는 수가 주어지며, 이 값은 100,000을 넘지 않는 양의 정수이다. 합이 M을 넘지 않는 카드 3장

www.acmicpc.net

 

뭐 보시면 알겠지만 아주 간단한 완전탐색문제인데, 같은 실수를 하지 않으려고 적는 것이지 내 풀이나 코드를 올리려는 게 아니어서 그것에 대해선 쓰지 않을 생각이다. 

어젯밤에 이걸 두시간 가까이 잡고 낑낑거리다가 에러의 이유를 도저히 몰라서 검색해보고 나서 엄청나게 허탈해졌다. 그리고 그렇게 삽질한 근본적인 원인은 처음부터 조건을 제대로 읽지 않았기 때문이다. 

 

 

아래는 내가 어제 쓰다 말았던 코드의 일부이다. (앞부분은 생략했다)

if sum == M:
  blackjack = M
  break
else:
  num_list.append(sum)
  output = min([abs(M - i) for i in num_list])
  if (M - output) in num_list:
    blackjack = M-output
  else:
    blackjack = M+output

print(blackjack)

 

나 대체 뭐 한 거임?

애초부터 문제에서는 '합이 M을 넘지 않는' 경우만 구하면 된다고 친절하게 명시를 해주었다(그것도-빨갛게 체크한 부분처럼-두 번이나!). 그러니까 주어진 숫자가 500이고 세 장 합계로 구할 수 있는 수 중에 497이랑 501이 있을 때 후자를 출력할 방법을 고민해서 절댓값을 짜낼 이유가 없었던 것이다. 

 

문제에 명시된 조건 좀 제대로 읽으라고 잔소리하던 강사가 훗날 문제의 조건을 제대로 읽지 않아서 귀중한 시간을 허공에 날리게 된다는 걸 예전의 내 학생들은 모르겠지. 얘들아, 보고 있니?