일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- Web
- DP
- 2020 KAKAO BLIND
- 구현
- 2019 KAKAO BLIND
- level 1
- next_permutation
- c++
- BFS
- 백준
- 월간 코드 챌린지
- Gold 5
- pass
- 시뮬레이션
- SWEA
- 코드리뷰
- 스택/큐
- 삼성 SW 역량 테스트
- 그리디
- 백트래킹
- 부스트코스
- Gold 4
- 2020 카카오 인턴십
- Level 2
- 프로그래머스
- 브루트포스
- Level 4
- Level 3
- 코드 리뷰
- DFS
- Today
- Total
Min:D's Devlog
[프로그래머스][그리디][C++] 조이스틱 본문
문제
프로그래머스 그리디 - 조이스틱
문제 설명
조이스틱으로 알파벳 이름을 완성하세요. 맨 처음엔 A로만 이루어져 있습니다.
ex) 완성해야 하는 이름이 세 글자면 AAA, 네 글자면 AAAA
조이스틱을 각 방향으로 움직이면 아래와 같습니다.
-
▲ - 다음 알파벳
-
▼ - 이전 알파벳 (A에서 아래쪽으로 이동하면 Z로)
-
◀ - 커서를 왼쪽으로 이동 (첫 번째 위치에서 왼쪽으로 이동하면 마지막 문자에 커서)
-
▶ - 커서를 오른쪽으로 이동
예를 들어 아래의 방법으로 JAZ를 만들 수 있습니다.
-
첫 번째 위치에서 조이스틱을 위로 9번 조작하여 J를 완성합니다.
-
조이스틱을 왼쪽으로 1번 조작하여 커서를 마지막 문자 위치로 이동시킵니다.
-
마지막 위치에서 조이스틱을 아래로 1번 조작하여 Z를 완성합니다. 따라서 11번 이동시켜 "JAZ"를 만들 수 있고, 이때가 최소 이동입니다.
만들고자 하는 이름 name이 매개변수로 주어질 때, 이름에 대해 조이스틱 조작 횟수의 최솟값을 return 하도록 solution 함수를 만드세요.
제한 사항
-
name은 알파벳 대문자로만 이루어져 있습니다.
-
name의 길이는 1 이상 20 이하입니다.
입출력 예
name | return |
JEROEN | 56 |
JAN | 23 |
문제 풀이
접근 방식
조이스틱을 움직이는 횟수는 이름을 구성하는 알파벳과 그 위치에 의해 결정된다.
1) 알파벳
A ~ N은 ▲ 방향으로 이동(0 ~ 13), Z ~ M은 ▼ 방향으로 이동(1 ~ 12)시켜야 최소 횟수로 변경할 수 있다.
총 이동 횟수 변수인 answer에 이 모든 횟수를 더한다.
2) 위치
초기에는 모든 알파벳이 A로 설정되어 있다. (Ex) AAA, AAAAAA)
그래서 바꿔야 할 이름의 알파벳 중 A인 경우에는 바꿀 필요가 없다.
따라서 조이 스틱을 최소 횟수로 이동시키기 위해 고려해봐야 할 이동 방향은 4가지이다.
-
▶ (): 뒷부분이 A인 경우 최소
Ex) BBBBAA이면 오른쪽으로 3번만 이동하면 됨
-
◀ :앞부분이 A인 경우 최소
Ex) AAAAABBB이면 왼쪽으로 3번만 이동하면 됨
-
▶◀ : 중간에 A가 많은 경우 중 앞부분에 A가 아닌 알파벳이 더 적은 경우
Ex) BBBAAAAAAAAABBBBB이면 오른쪽으로 2번, 왼쪽으로 2 + 5번. 즉, 2 * 2 + 5 = 9번만 이동하면 됨
-
◀▶ : 중간에 A가 많은 경우 중 뒷부분에 A가 아닌 알파벳이 더 적은 경우
Ex) BBBBBBBAAAAAAAAABBB이면 왼쪽으로 3번, 오른쪽으로 3 + 6번. 즉, 3 * 2 + 6 = 12번만 이동하면 됨
이 4가지 경우의 이동 횟수를 세기 위해 front, back, half_front, half_back 변수를 사용하였다.
그리고 front, back, half_front * 2 + half_back, half_back * 2 + half_front 중 최솟값을 answer에 더해주었다.
풀이 코드 - C++
#include <algorithm>
using namespace std;
int solution(string name) {
int len = name.size();
int mid = len / 2;
int front = 0;
int back = 0;
int half_front = 0;
int half_back = 0;
int answer = name[0] - 'A';
if(answer > 13)
answer = 'Z' - name[0] + 1 ;
for (int i = 1; i < len; i++) {
if (name[i] <= 'N')
answer += name[i] - 'A';
else
answer += 'Z' - name[i] + 1;
if (name[i] != 'A') {
front = i;
if (i <= mid)
half_front = i;
}
if (name[len - i] != 'A') {
back = i;
if (len - i > mid)
half_back = i;
}
}
answer += min(min(front, back), min(half_back * 2 + half_front, half_front * 2 + half_back));
return answer;
}
실행 결과
'알고리즘 > 프로그래머스' 카테고리의 다른 글
[프로그래머스][완전탐색][C++] 소수 찾기 (0) | 2020.07.10 |
---|---|
[프로그래머스][그리디][C++] 큰 수 만들기 (0) | 2020.07.06 |
[프로그래머스][그래프][C++] 가장 먼 노드 (0) | 2020.06.29 |
[프로그래머스][스택/큐][C++] 다리를 지나는 트럭 (0) | 2020.06.28 |
[프로그래머스][이분탐색][C++] 예산 (0) | 2020.06.27 |