강의로 돌아가기
김강진

C++ 극도로 상세하고 쉬운 풀이

1. 조이스틱 상/하 이동 최솟값 구하는(알파벳을 A에서 J 등 목표한 바로 바꾸는) 방법

A ~ N의 경우 N - character
O ~ Z의 경우 Z - character + 1

그래서 alphaMove[26]을 {0,1,2,3,4,5,6,7,8,9,10,11,12,13,12,11,10,9,8,7,6,5,4,3,2,1}; 같이 정의 할 수 있음

2. 조이스틱을 좌/우 이동 최솟값을 찾는 방법

Case1. 조이스틱을 원점에서 쭉 한 방향으로 이동하는 경우

name의 길이가 n일때 n-1번 이동하면 됨
ex. JKL 오른쪽으로 2번이동하면 됨

Case2. 조이스틱을 한 방향으로 이동시킨 후 다시 역방향으로 또 이동하는 경우

ex. JAZAAAP
이 사례에서 우린 먼저 원점에서 J를 다루고 왼쪽키를 눌러 P로 넘어간다.
P를 다룬 후 왼쪽으로 가게되면 A를 3번이나 만나게 되므로 오른쪽으로 방향을 바꾸어 이동한다.

이때 Case2는 또한 2가지로 나뉘게 된다
원점 기준 오른쪽 문자중 하나의 인덱스를 x라하고
x 다음의 문자들중 A가 아닌 문자의 인덱스를 y라 하자

Case2-1. 원점 기준 오른쪽으로 이동해 x까지 탐색하고 왼쪽으로 이동해 y를 탐색하는 경우

x + x + (n-y) : 오른쪽으로 x만큼 이동 + 왼쪽으로 x만큼 이동 + 왼쪽으로 (n-y)만큼 이동

Case2-1. 원점 기준 왼쪽으로 이동해 y까지 탐색하고 다시 오른쪽으로 이동해 y를 탐색하는 경우

(n-y) + (n-y) + x : 왼쪽으로 (n-y)만큼 이동 + 오른쪽으로 (n-y)만큼 이동 + 오른쪽으로 x만큼 이동

결론적으로 우린 Case2-1과 Case2-2중 작은 놈을 택해야 하기에
minMove = min(minMove, min(x+x+n-y, n-y+n-y+x) )를 해주어 minMove를 갱신한다

3. 결론

마지막으로 우리는 1번(조이스틱 상하 이동 최솟값)과 2번(조이스틱 좌우 이동 최솟값) 의 경우를 더해주어 answer를 찾으면 된다

#include<bits/stdc++.h>
using namespace std;

int solution(string name){
    int upDownMove[26] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,12,11,10,9,8,7,6,5,4,3,2,1};
    int ans = 0, n = name.size();
    int leftRightMove = n-1;
    for(int x = 0; x < n; x++){
        ans += upDownMove[name[x]-'A'];
        int y = x + 1; // x 오른쪽에 있으면서 A가 아닌 문자가 있는 위치를 y라하자
        while( y < n && name[y] == 'A') y++;
        leftRightMove = min( leftRightMove, min( x+x+(n-y), x+(n-y)+(n-y) ) );
    }
    ans += leftRightMove;
    return ans;
}
작성중인 코드―solution.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include<bits/stdc++.h>
using namespace std;

int solution(string name){
    int alphaMove[26] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,12,11,10,9,8,7,6,5,4,3,2,1};
    int ans = 0, n = name.size();
    int minMove = n-1;
    for(int x = 0; x < n; x++){
        ans += alphaMove[name[x]-'A'];
        int y = x + 1; // x 오른쪽에 있으면서 A가 아닌 문자가 있는 위치를 y라하자
        while( y < n && name[y] == 'A') y++;
        minMove = min( minMove, min( x+x+(n-y), x+(n-y)+(n-y) ) );
    }
    ans += minMove;
    return ans;
}
0 개의 답변
답변 쓰기
이 입력폼은 마크다운 문법을 지원합니다.