코딩 테스트 스터디/백준

[실버 IV] 17219번. 비밀번호 찾기

남쪽마을밤송이 2022. 5. 25. 16:34

 문제 

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

 

17219번: 비밀번호 찾기

첫째 줄에 저장된 사이트 주소의 수 N(1 ≤ N ≤ 100,000)과 비밀번호를 찾으려는 사이트 주소의 수 M(1 ≤ M ≤ 100,000)이 주어진다. 두번째 줄부터 N개의 줄에 걸쳐 각 줄에 사이트 주소와 비밀번

www.acmicpc.net

 사용 언어 

Python3

 풀이 과정 

solved.ac의 클래스 점수를 얻고 싶어서 관련 문제를 하나씩 풀어보려고 한다.

당연히(?) 쉬운 문제부터 푸는 중이라서 고른 문제인데 입출력 관련 문제였고 왜 실버지? 싶을 정도로 아주 쉬웠다.

 

처음 내가 짰던 코드는 다음과 같다.

from sys import stdin
input = stdin.readline

sites, toFind = map(int, input().split())
siteDict = {}
for _ in range(sites):
    site, passwd = input().split()
    siteDict[site] = passwd

for _ in range(toFind):
    print(siteDict[input().rstrip()])

이 코드로 한 번에 맞았습니다!!가 가능했지만 시간이 좀 아쉬워서 코드를 개선한 내용은 아래에 적어보겠다.

 제출 답안 

from sys import stdin, stdout

sites, toFind = map(int, stdin.readline().split())
siteDict = dict(stdin.readline().rstrip().split() for _ in range(sites))
for _ in range(toFind):
    stdout.write(siteDict[(stdin.readline().rstrip())] + '\n')

 공부한 내용 

sys.stdout.write( )

지금까지는 출력을 위해서 print( )만 사용했는데 이번에는 stdout.write( )를 사용했다.

 

 input( ) 보다  sys.stdin.readline( ) 이 더 빠른 것처럼

 print( ) 보다는  sys.stdout.write( ) 가 더 빠른 것이다.

 

저번에 구글링하다가 언뜻 본적이 있었지만 굳이 사용해보지 않다가

이번 문제처럼 출력이 많은 문제에서는 도움이 되었다.

 

그런데 sys.stdout.write()를 바꾸고 테스트해보지 않고 바로 제출했더니 틀렸습니다가 떴다!

출력해보니 print( ) 내장함수와 다르게 기본함수이기 때문에 줄바꿈이 기본적으로 들어가 있지 않았던 것이었다.

 

따라서 주의할 점은, 줄바꿈을 원한다면 아래와 같이  + '\n' 을 추가해주어야 한다는 것이다.

(개행을 위해서는 \n을 사용하는 것이 가장 빠르다고 한다)

stdout.write(siteDict[(stdin.readline().rstrip())] + '\n')

딕셔너리 초기화2

저번에 파이썬에서의 간편한 딕셔너리 초기화 방법을 공부했었는데,

# 틀린 코드
siteDict = {i: x for i, x in input().split() for _ in range(sites)}

위와 같이 입력값을 이용해서 그 방법을 사용하려고 하니까 애매해서 포기하고 다음과 같은 코드를 짰다.

siteDict = {}
for _ in range(sites):
    site, passwd = input().split()
    siteDict[site] = passwd

그런데  맞힌 사람 을 보다가 한 줄로 풀이할 방법을 알아냈다.

siteDict = dict(stdin.readline().rstrip().split() for _ in range(sites))

이렇게  dict( ) 로 감싸주면 안의 값이 2개인 list나 tuple일 경우 바로 딕셔너리의 key: value 형태로 들어가는 것 같았다.

정확하게 설명해놓은 관련 자료를 찾지 못해 아쉬운데 나중에 시간나면 찾아봐야겠다.

 코드 개선 

1. 일단 input으로 간단히 정의해서 사용한 것을 호출하는 형태였기 때문에 다 풀어서 직접 사용해줬다.

➡ 줄어들거라 예상은 했는데 입력이 많은 문제라 그런지 생각보다 많이 줄어들었다.

 

2. 그리고 if __name__ == "__main__":  안으로 넣어줬는데 오히려 4ms 늘어났다.

➡ 이거는 넣었을 때 시간이 줄어드는 경우 절반 오히려 미미하게 늘어나는 경우 절반인거 같은데 아직까진 이유를 모르겠다... 어쨌든 항상 줄어드는건 아니라는 것

 

3. 그리고 모든 출력을 sys.stdout.write( ) 함수로 바꿔줬다.

➡ 위에서 언급했듯이 줄바꿈이 안되어서 한 번 틀렸고 가장 큰 차이를 보였다!

 

4. 딕셔너리 value에 접근 방식을  [ ] 에서  .get(key) 로 변경해봤는데 시간의 차이가 없었다.

 

5. 마지막으로 딕셔너리 초기화를 한 줄로 변경했다.

4ms 더 줄어들게 성공!

 


간단한 문제지만 조금씩 고쳐서 시간이 줄어드는 걸 보면 기분좋다😆