조이스틱 문제
- 링크
프로그래머스
SW개발자를 위한 평가, 교육의 Total Solution을 제공하는 개발자 성장을 위한 베이스캠프
programmers.co.kr
문제 핵심
1.
"조이스틱으로 알파벳 이름을 완성하세요. 맨 처음엔 A로만 이루어져 있습니다.
ex) 완성해야 하는 이름이 세 글자면 AAA, 네 글자면 AAAA"
이말인 즉, 전부 'A'부터 시작한다는 점을 알야둬야함
2.
"▲ - 다음 알파벳
▼ - 이전 알파벳 (A에서 아래쪽으로 이동하면 Z로)
◀ - 커서를 왼쪽으로 이동 (첫 번째 위치에서 왼쪽으로 이동하면 마지막 문자에 커서)
▶ - 커서를 오른쪽으로 이동 (마지막 위치에서 오른쪽으로 이동하면 첫 번째 문자에 커서)"
처음 이것 때문에 헷갈렸는데 '◀' 와 '▶'는 문자열 인덱스를 옮기는 것임
예를 들어
ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ
초기 상태: [A][A][A]
↑
커서 위치 0
상하 이동 ▲ 9번: [J][A][A]
↑
커서는 여전히 위치 0
좌우 이동 ◀ 1번: [J][A][A]
↑
커서가 위치 2로 이동
ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ
라는 것이죠
문제풀이
public int solution(string name)
{
int answer = 0;
var maxcount = name.Length;
for(int i = 0; i < maxcount; i++)
{
var updowncount = name[i] - 'A';
var downupcount = 'Z' - name[i] + 1;//+1은 A에서 왼쪽 또는 아래 버튼을 이용하여 이동하는 횟수
answer += Math.Min(updowncount, downupcount);
}
return answer;
}
- updowncount는 'A'에서 부터 name[i]까지 도달하는 횟수
- downupcount는 'Z'에서 부터 name[i]까지 도달하는 횟수 'A'에서 'Z'로 이동하는 횟수 +1
*'A'는 아스키코드로 계산
설명
- updowncount와 downupcount중에 더 작은 횟수를 찾아서 answer에 추가
var mincount = maxcount - 1;//오른쪽으로 한칸씩 이동했을때 횟수
for(int i = 0; i < maxcount; i++)
{
var updowncount = name[i] - 'A';
var downupcount = 'Z' - name[i] + 1;//+1은 A에서 왼쪽 또는 아래 버튼을 이용하여 이동하는 횟수
answer += Math.Min(updowncount, downupcount);
//연속 'A'구간 넘어가기 위한 처리
int next = i + 1;
while(next < maxcount && name[next] == 'A')
{
next++;
}
//매 위치마다 여기서 돌아갈지를 체크
mincount = Math.Min(mincount, i * 2 + maxcount - next);//우좌
mincount = Math.Min(mincount, (maxcount - next) * 2 + i);//좌우
}
- 여기서 핵심은 좌우이동에 관련된 로직이라는 점입니다.
◀ - 커서를 왼쪽으로 이동 (첫 번째 위치에서 왼쪽으로 이동하면 마지막 문자에 커서)
▶ - 커서를 오른쪽으로 이동 (마지막 위치에서 오른쪽으로 이동하면 첫 번째 문자에 커서)
도 전부 횟수에 추가가 되기 때문에 감안하고 추가해야합니다.
맨처음
ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ
var mincount = maxcount - 1;
ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ
오른쪽으로 한칸씩 이동 시켰을때 총 횟수 입니다.
이것을 기반으로 여러 방법들중 제일 작은 횟수를 answer에 추가해줄 것입니다.
ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ
//연속 'A'구간 넘어가기 위한 처리
int next = i + 1;
while(next < maxcount && name[next] == 'A')
{
next++;
}
ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ
를 이용해서 'A'인 구간들은 뛰어 넘어줍니다.
ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ
//매 위치마다 여기서 돌아갈지를 체크
mincount = Math.Min(mincount, i * 2 + maxcount - next);//우좌
mincount = Math.Min(mincount, (maxcount - next) * 2 + i);//좌우
ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ
를 이용하여 총 두가지 방식에 대한 것을 비교 해줄 것입니다.
첫번째 i * 2 + maxcount - next는
"0 → 1 → 2 → 0 → 7
(R까지 2번) + (시작으로 돌아가기 2번) + (N으로 1번) = 5번"
이러한 방식으로 오른쪽으로 갔다 왼쪽으로 돌아오는 방식입니다.
두번째 (maxcount - next) * 2 + i는
"0 → 7 → 0 → 1 → 2
(N으로 1번) + (시작으로 돌아가기 1번) + (R까지 2번) = 4번"
로 왼쪽갔다가 오른쪽으로 이동하는 방식입니다.
이 두가지 방식을 이용해 어느구간이 제일 짧게 하는지 매번 문자열의 index위치마다 체크하여 제일 짧은 구간을 answer에 넣어주면 끝
최종코드
using System;
public class Solution
{
public int solution(string name)
{
int answer = 0;
var maxcount = name.Length;
var mincount = maxcount - 1;//오른쪽으로 한칸씩 이동했을때 횟수
for(int i = 0; i < maxcount; i++)
{
var updowncount = name[i] - 'A';
var downupcount = 'Z' - name[i] + 1;//+1은 A에서 왼쪽 또는 아래 버튼을 이용하여 이동하는 횟수
answer += Math.Min(updowncount, downupcount);
//연속 'A'구간 넘어가기 위한 처리
int next = i + 1;
while(next < maxcount && name[next] == 'A')
{
next++;
}
//매 위치마다 여기서 돌아갈지를 체크
mincount = Math.Min(mincount, i * 2 + maxcount - next);//우좌
mincount = Math.Min(mincount, (maxcount - next) * 2 + i);//좌우
}
return answer + mincount;
}
}
'알고리즘(코테 대비) > 코딩 테스트 문제 풀이(C#)' 카테고리의 다른 글
| [Lv.2] 큰 수 만들기(고득점 알고리즘 Kit Greedy) (0) | 2025.09.23 |
|---|---|
| [Lv.1] 유연근무제 (0) | 2025.08.19 |