https://school.programmers.co.kr/learn/courses/30/lessons/42860?language=cpp
참고
#include <string>
#include <vector>
#include <iostream>
#include <algorithm>
// https://googleyness.tistory.com/entry/C-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EC%A1%B0%EC%9D%B4%EC%8A%A4%ED%8B%B1
#define min(a,b) ((a) > (b) ? (b) : (a))
using namespace std;
int alpha_to_move[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 solution(string name)
{
int answer = 0;
int n = name.size();
// case 1 : 한방향으로 조이스틱 계속 움직일 때 최소 이동 거리
int min_move = n;
for (int x = 0; x < n; ++x)
{
// 해당 위치에서의 조작 횟수
answer += alpha_to_move[name[x] - 'A'];
// case 2 : 조이스틱을 원점 기준으로 한 방향으로 이동시키며 탐색하다가
// 다시 그 역방향으로 탐색할 때가 더 최소 거리일 수 있다.
// 최초 원점 기준 오른쪽 문자 중 하나의 idx 를 x 라고 하고
// 그 다음 'A'가 아닌 문자의 idx 를 y 라고 한다.
// 1) 원점 기준으로 x 까지 탐색하고 , 다시 역방향으로 y 를 탐색했을 때 이동 거리
// 2) 원점 기준으로 역방향으로 y 탐색 이후, 다시 정방향으로 x 탐색했을 때 이동 거리
int y = x + 1;
while(y < n && name[y] == 'A') y++;
int case1 = x + x + (n - y); // x 로 이동, 다시 원점으로, 역으로 y까지
int case2 = (n - y) + (n - y) + x; // 역으로 y, 다시 원점, x까지
int nxt_move = min(case1, case2);
min_move = min(min_move, nxt_move);
}
answer += min_move;
return answer;
}