주녘공부일지

[프로그래머스 C#] Lv.2 조이스틱 본문

Programmers - C#/CodingTest Lv.2

[프로그래머스 C#] Lv.2 조이스틱

주녘 2024. 3. 16. 21:17
728x90

https://school.programmers.co.kr/learn/courses/30/lessons/42860

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

1. 정답코드 및 핵심 아이디어, 유의사항

조이스틱으로 알파벳 이름을 완성할 때 최소 조이스틱 이동 횟수를 구하는 문제

- 초기 알파벳은 모두 A로 시작하여 주어진 이름을 완성하기 위한 최소 조이스틱 이동 횟수

- 양쪽 끝은 이어져있음 ( 0번에서 좌측이동 시, 오른쪽 끝으로 )

 

좌우 이동 최소 횟수와 위아래 이동 최소 횟수를 나누어 연산

- 좌우 이동과 위아래 이동은 서로 영향을 미치지 않기 때문에 따로 연산

 

위아래 이동 최소 횟수 구하기

- 위로 이동하는 경우와 아래로 이동하는 경우를 비교해 작은 값으로 세팅

 

좌우 이동 최소 횟수 구하기

좌우 이동하여 'A'가 아닌 모든 문자에 접근하는데, 최소 이동 횟수를 구하기 위해서는 이동 방향을 두번 이상 바꿀 필요가 없음 ( 두번 이상 바꾸지 않아야 함 )

- 방향을 바꾸지 않고 한 방향으로 가는 경우

- 오른쪽으로 가다가 왼쪽으로 가는 경우

- 왼쪽으로 가다가 오른쪽으로 가는 경우

 

핵심 아이디어 ( 좌우 이동 최소 횟수 )

A로만 이루어진 부분문자열들의 시작점과 끝점을 기준으로 좌우의 방문해야 하는 영역을 나누어 연산

 - 만약 진행 방향을 변경하 경우 이미 지나온 길을 돌아가야 함 ( x 2 )

 + 좌우 이동은 경우의 수에 따른 이동 횟수를 모두 확인해 최소 이동 횟수를 구함

 

주석 참조

    using System;

    public class Solution
    {
        public int solution(string name)
        {
            int answer = 0;

            // 1. 좌우 이동 최소 횟수 구하기
            answer = name.Length - 1; // 한 방향으로 가는 경우
          	
            // 0번 인덱스는 좌우 이동이 필요하지 않으므로 1부터 순회
            for (int i = 1; i < name.Length; i++)
            {
                // A를 발견하면 A로된 부분문자열을 기준으로 좌우 영역을 나누어 계산
                if (name[i] == 'A')
                {
                    int left = i - 1; // 왼쪽 영역 개수
                    while (i < name.Length && name[i] == 'A')
                        i++;
                    int right = name.Length - i; // 오른쪽 영역 개수

                    answer = Math.Min(answer, 2 * right + left); // 오른쪽 -> 왼쪽
                    answer = Math.Min(answer, 2 * left + right); // 왼쪽 -> 오른쪽
                }
            }

            // 2. 위아래 이동 최소 횟수 구하기
            for (int i = 0; i < name.Length; i++)
            {
                if (name[i] == 'A')
                    continue;

                int upCount = name[i] - 'A';
                int downCount = 'Z' - name[i] + 1;

                answer += Math.Min(upCount, downCount);
            }

            return answer;
        }
    }
728x90