문제
상근이의 할머니는 아래 그림과 같이 오래된 다이얼 전화기를 사용한다.
전화를 걸고 싶은 번호가 있다면, 숫자를 하나를 누른 다음에 금속 핀이 있는 곳 까지 시계방향으로 돌려야 한다. 숫자를 하나 누르면 다이얼이 처음 위치로 돌아가고, 다음 숫자를 누르려면 다이얼을 처음 위치에서 다시 돌려야 한다.
숫자 1을 걸려면 총 2초가 필요하다. 1보다 큰 수를 거는데 걸리는 시간은 이보다 더 걸리며, 한 칸 옆에 있는 숫자를 걸기 위해선 1초씩 더 걸린다.
상근이의 할머니는 전화 번호를 각 숫자에 해당하는 문자로 외운다. 즉, 어떤 단어를 걸 때, 각 알파벳에 해당하는 숫자를 걸면 된다. 예를 들어, UNUCIC는 868242와 같다.
할머니가 외운 단어가 주어졌을 때, 이 전화를 걸기 위해서 필요한 시간을 구하는 프로그램을 작성하시오.
정리>> A,B,C:3회, D,E,F:3회, ...
입력
첫째 줄에 알파벳 대문자로 이루어진 단어가 주어진다. 단어는 2글자~15글자로 이루어져 있다.
출력
첫째 줄에 다이얼을 걸기 위해서 필요한 시간을 출력한다.
문제출처: https://www.acmicpc.net/problem/5622
풀이 과정
.
.
.
.
.
.
.
.
.
.
#1. Dictionary
- alphabet과 dial을 매칭한 dictionary를 생성한다.
list+=list
보다list.extend(list)
성능이 더 좋다.
Alphabet list
alpha=list(map(chr,list(range(ord('A'),ord('Z')+1))))
#or
alpha = list(map(chr, range(65, 91)))
갯수 리스트 만들기
- 방법1. 다이얼을 정해진 갯수만큼 직접 추가
d=[]
for i in range(3,8):d.extend([i]*3)
d.extend([8]*4+[9]*3+[10]*4)
print(d)
#[2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 9, 9, 9, 9]
- 방법2. 다이얼과 갯수를 dictionary로 만들어 합치기
alpha = list(map(chr, range(65, 91)))
d=[]
splt={2:3,3:3,4:3,5:3,6:3,7:4,8:3,9:4}
for dial,n in splt.items():
d.extend([dial]*n)
print(d)
#[2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 9, 9, 9, 9]
- 방법3. 위와같다.
nums=[3,3,3,3,3,4,3,4]
d=[]
for idx, dial in enumerate(range(2,10)):
d.extend([dial]*nums[idx])
print(d)
#[2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 9, 9, 9, 9]
알파벳 리스트와 갯수 리스트를 dictionarify
alpha = list(map(chr, range(65, 91)))
dict(zip(alpha,d))
#or
{a:b for a,b in zip(alpha,d) }
#{'A': 3,
'B': 3,
'C': 3,
완성
txt=input()
alpha = list(map(chr, range(65, 91)))
nums=[3,3,3,3,3,4,3,4]
d=[]
for idx, dial in enumerate(range(2,10)):
d.extend([dial]*nums[idx])
dial=dict(zip(alpha,d))
print(sum([dial[i]+1 for i in txt]))
#2. 나눗셈의 몫
- step(여기서는 3)으로 나눈 몫을 이용하여
(ord(s)-65)//3 +3
으로 앞에서 3개씩 나누어 3,4,... 으로 반환 가능하다. - SVYZ인 이유는 앞에서부터 3으로 나눴을 때 한칸씩 밀리는 알파벳들이다.
x=input()
print(sum((ord(s)-65)//3+3 for s in x)-sum(x.count(s) for s in 'SVYZ'))
예를 들어 ord('A')
값은 65이다. A,B,C
를 ord
함수 적용하여 65를 빼면 0,1,2
이며, 3으로 나눈 몫은 0이다. 이에 3을 더하면 A,B,C
는 3,3,3
을 반환한다.
연속적인 수열//step+initial
와 같이 몫을 이용하면 step별로 규칙적인 수를 반환할 수 있다. 몫은 step 구간 개념으로 이용 가능하다.
SVYZ를 따로 계산한 이유는, 알파벳을 처음부터 3개씩 나눴을 때, 문제에서 주어진 구간과 달라지는 알파벳들이 S,V,Y,Z이다. 이들을 각각 한 단계씩 앞으로 보내면 문제에서 주어지는 알파벳 그룹과 같게 된다.
'Python > Algorithm' 카테고리의 다른 글
정수를 자릿수별로 쪼개기 (0) | 2020.03.12 |
---|---|
한수 (0) | 2020.03.12 |
Self number 셀프 넘버 (0) | 2020.03.12 |
숫자 배열에서 K번째 큰 값 찾기 (0) | 2020.03.10 |
숫자 배열에서 두 번째로 큰 값 찾기 (0) | 2020.03.10 |