크게 어려운 문제를 풀려고 시작한 건 아니고... 문제를 많이 풀어보면서 파이썬 문법과 친해지려는 목적이 가장 크다.
그래서 문제도 알고리즘보다는 단순 구현에 집중된 문제를 주로 보려고 하고, 이 글에서도 파이썬의 어떤 요소를 사용해서 문제를 해결했는지를 설명하고자 한다.
그러면 시작
뭐 다양한 방법이 있을 수 있을 것 같은 매우 단순한 문제인데...
일단 브루트포스는 안 통한다. 대충 계산해봐도 백 억 번 연산을 해야 하기도 하고 무엇보다...
전에 C로 브루트포싱 했다가 시간초과났다. ㅋ
그러면 바로 떠올릴 수 있는 건 크게 두 가지다.
뭔가 알고리즘을 파고 싶으면 당연히 2를 고르겠지만 위에도 말했듯이 파이썬의 여러 문법에 적응하고자 하는 취지이기 때문에 1로 가보겠다. ㅎㅎ
n = input()
a = set(map(int, input().split()))
m = input()
b = map(int, input().split())
for i in b:
if i in a :
print(1)
else:
print(0)
여기서 볼 건 크게 두 가지이다.
파이썬에서 한 줄을 통째로 input받고 이를 쪼개려면 split을 해야 한다.
그런데, split 함수를 사용하면 리스트에 들어가는 값들이 모두 문자열이 된다는 문제가 존재한다.
따라서 int 함수를 사용해서 리스트 안의 모든 원소들을 정수형으로 바꿔줘야 하는데, 이 과정에서 배열 전체에 함수를 적용할 수 있도록 하는 함수가 바로 map이다. 따라서 map(int, input().split())이라는 파이썬으로 백준을 풀어본 사람이라면 모두 본 적 있을 코드가 완성된다...ㅎ
거기에 한 술 더 떠서 a를 input 받을 때에는 map을 set 함수로 감싸주었다. set 함수는 list를 set으로 변환해주기 때문에, 원래 리스트였던 결과가 set으로 바뀌게 된다!
이걸 보니 자바스크립트 하면서 함수형 프로그래밍 어쩌구,, 때문에 너무나도 고통받았던 시기가 문득 떠오른다...^^ 요즘 언어들은 참... 외울 게 많은 것 같다.
점프 투 파이썬은 아무래도 일반인들을 주로 대상으로 한 책이기 때문에 좀... 빠진 내용이 많은 것 같다. 이 책 말고 딴 걸로 할 걸 그랬나 후회 중이다.
c++을 예시로 들자면, 거기서는 set의 원소를 찾는 데 find를 사용한다. 하지만! 파이썬은 in 연산자가 기본적으로 제공된다. 해당하는 원소가 그 컨테이너에 존재하면 True, 아니면 False를 리턴하는 아주 편리한 연산자이다.
따라서 그냥 바로 이렇게 찾아주면 된다.
if i in a :
print(1)
else:
print(0)
그래서 사실 꼭 여기서 set 안 써도 될 것 같고...? 근데 set 쓰는 게 더 빠를 것 같기도 하고 모르겠다. 여기 set은 어떻게 구현된 건지까지는 몰라서... 그 background를 봐야 알 듯
따라서 전체 코드는 다음과 같다.
n = input()
a = set(map(int, input().split()))
m = input()
b = map(int, input().split())
for i in b:
if i in a :
print(1)
else:
print(0)
얘는 소트다. 뭐... 간단하죠?
거기에 2차원 배열을 쓰까봤다.
이 문제를 처음 보고 c++이면 어떻게 풀었을까? 생각해봤다. 사실 비슷한 문제를 풀었었는데, 그 때 값과 인덱스를 pair로 묶어서 저장하고 리스트에 넣었던 기억이 떠올랐다.
그래서 똑같이 구현했는데, 대신 python은 pair 같은 자료형이 있을 필요 없이 그냥 리스트의 요소를 자유롭게 할 수 있기 때문에 리스트 안에 리스트를 넣는 식으로 해서 구현했다! 이런 점에서는 확실히 파이썬이 편하다.
거기에 정렬을 몇 번 했는데, 이건 별 거 없다. 알아둘 점은 크게 두 개다.
list = list.sort()
이렇게 되면 list에 그냥 None이 대입돼 버린다.
list.sort()
이렇게 하면 별도의 대입 없이 바로 list가 정렬된 상태로 저장된다.
만약 역방향으로 정렬을 하고 싶다면, 다음과 같이 할 수 있다.
list.sort(reverse=True)
정렬의 경우, sorted 함수를 이용해서 다양한 요소를 기준으로 해서 정렬할 수도 있고, 아니면 아예 lambda를 가지고 완전 마음대로 커스텀도 가능하다. 이런 점 관련해서는 나중에 정리를 해... 보도록... 하겠다...^^ (언제가 될지는 모름)
그리고 사실 예상하기는 했는데, 이 경우처럼 2차원 배열을 딱히 아무 기준도 주지 않고 정렬하면 맨 앞 요소를 기준으로 해서 정렬된다! 참고할 것.
완성된 코드는 다음과 같다.
l = []
for i in range(8):
t = int(input())
l.append([t, i+1])
l.sort(reverse=True)
s = 0
ans = []
for i in range(5):
s += l[i][0]
ans.append(l[i][1])
print(s)
ans.sort()
for i in ans:
print(i, end=' ')
소감은... 음
확실히 사람들이 코테 입문으로 파이썬을 많이 쓰는 이유를 알 것 같다. 정말 직관적이다. 그래서 코드짜기 편하다. 물론 적응이 되어야 그런 거긴 하다. 사실 난 아직도 c++이 조금 더 편한 것 같기는 하다. ㅋㅋㅋㅋㅜㅜㅜ 뭔가 c++ 뇌에서 파이썬으로 번역하는 듯한 느낌이 없지 않아 있다...
뭐 연습하다 보면 적응할 거라고 믿는다. 그러면 조금 더 어려운 문제도 풀 수 있겠지?
다음은 컨테이너 내장 함수 관련된 문제를 조금 더 보고 싶다. 빡센 정렬 문제도 좋고... 그렇게 해서 좀 적응되었다 싶으면 바로 골드 풀이로 가도록 하겠다.