https://www.acmicpc.net/problem/20436
20436번: ZOAC 3
첫 번째 줄에는 두 알파벳 소문자 sL, sR이 주어진다. sL, sR은 각각 왼손 검지손가락, 오른손 검지손가락의 처음 위치이다. 그 다음 줄에는 알파벳 소문자로 구성된 문자열이 주어진다. 문자열의
www.acmicpc.net
쉬워서, 구현보다는 효율을 신경썼어야 했다.
그래서 pythonic한 것에 대해 배울 수 있었던 기회
문제를 처음보고
# 각 글자의 위치를 검색할 수 있는 data
# 각 글자가 자음인지 / 모음인지를 판단할 수 있는 data
for char in word :
# 모음 / 자음 판단
# if 모음 : 모음 예전거리 ~ 모음 현재거리 계산
# cnt += NN
# else : 자음 예전거리 ~ 자음 현재거리 계산
# cnt += NN
# cnt += 1 # 누르는 시간
이렇게 틀을 잡았다.
구현은 쉬울 것 같아서 어떻게 가장 빠른 자료구조를 쓸 수 있을지 생각했다.
처음엔 딕셔너리가 리스트보다 검색이 빠르니까, {'a' : (1,2) ,,,} 처럼 알파벳에 따른 위치를 기록해둘까 했다.
근데 어차피 알파벳이 ascii코드로 쭈루룩 있으니까 잘 활용해서 그냥 바로 인덱스로 접근하도록 하는게 낫겠다. 싶었다.
파이썬으로 ascii 코드를 확인하는건 ord()함수 를 사용하면 된다고한다!
+) 한번 정해진 좌표는 바뀔일 없으니까, 안전하게 set으로 선언하자
그럼 렛츠기릿해보자고
코드
# arr = [a(1,0), b(2, 4), c(2, 2), d(1, 2), e(0, 2), f(1, 3), g(1, 4), h(1, 5), i(0, 7), j(1, 6), k(1, 7), l(1, 8), m(2, 6), n(2, 5), o(0, 8) ,p(0, 9), q(0, 0), r(0, 3), s(1,1) ,t(0, 4), u(0, 6), v(2, 3),w(0, 1), x(2, 1), y(0, 5), z(3, 0)]
position_list = [(1,0), (2, 4), (2, 2), (1, 2), (0, 2), (1, 3), (1, 4), (1, 5), (0, 7), (1, 6), (1, 7), (1, 8), (2, 6),(2, 5), (0, 8) ,(0, 9), (0, 0),(0, 3), (1,1) ,(0, 4), (0, 6), (2, 3),(0, 1), (2, 1), (0, 5), (2, 0)]
jaeum_dict = {'q', 'w', 'e', 'r', 't', 'a', 's', 'd', 'f', 'g', 'z', 'x', 'c', 'v'}
moeum_dict = {'y', 'u', 'i', 'o', 'p', 'h', 'j', 'k', 'l', 'b', 'n', 'm'}
prior_left_pos, prior_right_pos = map(str, input().split())
word = input()
prior_left_pos, prior_right_pos = position_list[ord(prior_left_pos)-97], position_list[ord(prior_right_pos)-97]
cnt = 0
for char in word :
# 모음 / 자음 판단
if char in jaeum_dict : # 자음인경우
cur_pos = position_list[ord(char)-97]
cnt += abs(prior_left_pos[0] - cur_pos[0]) + abs(prior_left_pos[1] - cur_pos[1])
prior_left_pos = cur_pos
else : # 모음인경우
cur_pos = position_list[ord(char)-97]
cnt += abs(prior_right_pos[0] - cur_pos[0]) + abs(prior_right_pos[1] - cur_pos[1])
prior_right_pos = cur_pos
cnt += 1
print(cnt)

와 실버라서 그런지 1트 통과!!
시간복잡도 확인
쉬운 문제니까 '돌아가는게 중요' 하기 보다 '얼마나 효율적인가' 가 관건인 문제 같다.
나는 키보드에서의 위치를 하나하나 리스트로 하드코딩해서 만드는게 귀찮았지만,, 귀찮은만큼 속도가 괜찮았으면 하는 바램이다!!
그럼 남들의 속도를 보러 가볼까?

.........................................................................
거의 남들에 비해 두배 더 많은 시간이 걸렸다
메모리도 배로 썼다 ㄱ-
하하 쓰발 누가 pythonic하게 야무지게 짰을꼬....
한수 배우러 간다
한수배워요
keyboard = ["qwertyuiop", "asdfghjkl", "zxcvbnm"]
# dictionary 형태로 key 위치 기록
key = dict()
for r in range(len(keyboard)):
for c in range(len(keyboard[r])):
key[keyboard[r][c]] = (r, c)
prior_left, prior_right = input().split()
word = input().rstrip()
prior_left = key[prior_left]
prior_right = key[prior_right]
end_l = [5,5,4] # 자음 / 모음 판단할 기준 # 첫째줄 모음이 시작하는 column index / 두번째줄 ... / 세번째줄...
time = 0
for ch in word:
r, c = key[ch] # dictionary에서 key 위치 검색
if c < end_l[r]: # 자음인경우
time += abs(prior_left[0] - r) + abs(prior_left[1] - c)
prior_left = (r, c)
else: # 모음인경우
time += abs(prior_right[0] - r) + abs(prior_right[1] - c)
prior_right = (r, c)
print(time + len(word))
와! 천재다!
1) dictionary에 일일이 위치를 하드코딩 하지 않았다.
나는 위치를 코드로 자동화해서 알아내는 과정도 시간복잡도가 아까웠는데,
어차피 이정도 문제면 30분안에 풀어내야하니까 그냥 26번 반복문 돌리는게 더 나았다.
2) list를 indexing으로 접근하는 것보다 dictionary를 searching으로 접근하는게 더 빠르구나
와 첨알았다. 막연히 '아무리 dictionary라고 해도 searching이니까, list indexing이 더 빠르겠지' 라고 생각했었다.
아니구만 ㅈㅅㅎㄴㄷ!
나중에 time log 찍어서 한번 확인하거나 관련된 글을 찾아서 포스팅 함 해야겠다.
3) 자음 모음 판단하는게 깔끔하다!
이건 그냥 발상이 천재세요
당신의 아이디어를 back get some me down
'알고리즘 풀이' 카테고리의 다른 글
| [#1010] 다리놓기 (1) | 2022.11.22 |
|---|---|
| [#1316] 그룹단어 체커 (0) | 2022.11.21 |
| [#2217] 로프 (0) | 2022.11.18 |
| [#16234] 인구이동 (0) | 2022.11.16 |
| [#1325] 효율적인 해킹 (0) | 2022.11.15 |