https://school.programmers.co.kr/learn/courses/30/lessons/42860#
문제 설명
조이스틱으로 알파벳 이름을 완성하세요. 맨 처음엔 A로만 이루어져 있습니다.
ex) 완성해야 하는 이름이 세 글자면 AAA, 네 글자면 AAAA
조이스틱을 각 방향으로 움직이면 아래와 같습니다.
▲ - 다음 알파벳
▼ - 이전 알파벳 (A에서 아래쪽으로 이동하면 Z로)
◀ - 커서를 왼쪽으로 이동 (첫 번째 위치에서 왼쪽으로 이동하면 마지막 문자에 커서)
▶ - 커서를 오른쪽으로 이동 (마지막 위치에서 오른쪽으로 이동하면 첫 번째 문자에 커서)
예를 들어 아래의 방법으로 "JAZ"를 만들 수 있습니다.
- 첫 번째 위치에서 조이스틱을 위로 9번 조작하여 J를 완성합니다.
- 조이스틱을 왼쪽으로 1번 조작하여 커서를 마지막 문자 위치로 이동시킵니다.
- 마지막 위치에서 조이스틱을 아래로 1번 조작하여 Z를 완성합니다.
따라서 11번 이동시켜 "JAZ"를 만들 수 있고, 이때가 최소 이동입니다.
만들고자 하는 이름 name이 매개변수로 주어질 때, 이름에 대해 조이스틱 조작 횟수의 최솟값을 return 하도록 solution 함수를 만드세요.
제한 사항
입출력 예
name | return |
---|---|
"JEROEN" | 56 |
"JAN" | 23 |
import string
def solution(name):
min_move = len(name) -1
cnt = 0
while name[min_move] == 'A' and min_move > 0 : #마지막이 A일 때
min_move -= 1
if min_move < 0 : return 0 #전부 A면 0리턴
for i, l in enumerate(name):
cnt += min(ord(l)-ord('A'), ord('Z')-ord(l)+1) # 상하좌우 적게 이동
# A탐색
next = i + 1
while next < len(name) and name[next] == 'A':
next += 1 #연속되는 A중에서, 마지막으로 A인 곳
min_move = min_move = min([min_move, 2 *i + len(name) - next, i + 2 * (len(name) -next)])
return min_move+cnt
BAAAB
랑 BABABAB
테스트케이스 추가해보고 나혼자 열심히 코딩하다가 결국 아이디어가 떠오르지 않아 구글링을...^^ (참고 - https://velog.io/@jqdjhy/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%ED%8C%8C%EC%9D%B4%EC%8D%AC-%EC%A1%B0%EC%9D%B4%EC%8A%A4%ED%8B%B1-Greedy)
min_move = len(name) -1 cnt = 0
초기에 최소이동횟수를 문자열의 개수로 둔다.
while name[min_move] == 'A' and min_move > 0 : #마지막이 A일 때 min_move -= if min_move < 0 : return 0 #전부 A면 0리턴
마지막 글자가 A일 때 최소이동횟수를 줄인다.
최소이동횟수가 0이하가 되면 0을 리턴한다.
for i, l in enumerate(name): cnt += min(ord(l)-ord('A'), ord('Z')-ord(l)+1) # 상하좌우 적게 이동
알파벳을 효율적이게 바꾸는 알고리즘이다. 예를 들어 알파벳이 B이면 1과 25중에서 더 작은 값을 비교한다.
# A탐색 next = i + 1 while next < len(name) and name[next] == 'A': next += 1 #연속되는 A중에서, 마지막으로 A인 곳 min_move = min_move = min([min_move, 2 *i + len(name) - next, i + 2 * (len(name) -next)])
A들 중에서 마지막으로 A인 곳을 알아낸다.
왼쪽에서 오른쪽으로 탐색 후 A를 만나면 왼쪽편으로 되돌아가면서 맨 오른쪽부터 재탐색하는 게 짧은지
아니면 시작부터 오른쪽에서 왼쪽으로 탐색한 후 A를 만나면 오른쪽으로 되돌아가 맨 왼쪽부터 재탐색하는 게 짧은지
그것도 아니면 min_move가 가장 짧은지 선택한다.
다른사람의 풀이 찾아봤는데 죄다 반박 댓글이 있어서 가져오지 못했다......
너무 어렵다......내 수준에 안맞는 문제를 만나버렸어
레벨1이랑 2랑 수준차이 너무 나는데??? 다시 백준 실버부터 풀어야되나